AkelPad Forum Index AkelPad
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Scripts collection
Goto page Previous  1, 2, 3 ... 7, 8, 9 ... 16, 17, 18  Next
 
Post new topic   Reply to topic    AkelPad Forum Index -> Plugins
View previous topic :: View next topic  
Author Message
KDJ



Joined: 06 Mar 2010
Posts: 1263
Location: Poland

PostPosted: Sat Nov 13, 2010 6:26 pm    Post subject: Reply with quote

Brackets - go to or select between nearest brackets.

BracketsGoTo.js

Code:
// BracketsGoTo.js - ver. 2013-08-22 (x86/x64)
//
// Go to or select between nearest brackets.
//
// Usage:
// Call("Scripts::Main", 1, "BracketsGoTo.js", "l") - go to left to opening bracket
// Call("Scripts::Main", 1, "BracketsGoTo.js", "r") - go to right to closing bracket
// Call("Scripts::Main", 1, "BracketsGoTo.js", "L") - select between the brackets from left
// Call("Scripts::Main", 1, "BracketsGoTo.js", "R") - select between the brackets from right
//
// Can assign shortcut keys, eg: Ctrl+<, Ctrl+>, Ctrl+Shift+<, Ctrl+Shift+>.
// To change a set of brackets, change the value nABrackets variable.

var nABrackets = 1;
var aOpen;
var aClose;

if (nABrackets == 0)
{
  aOpen  = ["(", "[", "{", "<", "'", "\"", "/"];
  aClose = [")", "]", "}", ">", "'", "\"", "/"];
}
else if (nABrackets == 1)
{
  aOpen  = ["(", "[", "{", "'", "\""];
  aClose = [")", "]", "}", "'", "\""];
}
else if (nABrackets == 2)
{
  aOpen  = ["(", "[", "{"];
  aClose = [")", "]", "}"];
}
else if (nABrackets == 3)
{
  aOpen  = ["'", "\""];
  aClose = ["'", "\""];
}

var hEditWnd = AkelPad.GetEditWnd();
var sAction;

if (! hEditWnd)
  WScript.Quit();
if (WScript.Arguments.length)
  sAction = WScript.Arguments(0);
if (! sAction)
  WScript.Quit();

var nCarPos   = GetOffset(hEditWnd, 5 /*AEGI_CARETCHAR*/);
var nLastChar = GetOffset(hEditWnd, 2 /*AEGI_LASTCHAR*/);
var sTxt      = AkelPad.GetTextRange(0, nLastChar, 1 /*\r*/);
var sCarChar  = AkelPad.GetTextRange(nCarPos, nCarPos + 1);
var bSelAll   = false;
var nPos;
var nBrack;
var nBrackPos;
var nBegSel;
var nEndSel;
var i;

if ((sAction == "l") && (nCarPos > 0))
{
  nBrackPos = -1;
  for (i = 0; i < aOpen.length; ++i)
  {
    nPos = sTxt.lastIndexOf(aOpen[i], nCarPos - 1);
    if (nPos > nBrackPos)
      nBrackPos = nPos;
  }
  if (nBrackPos > -1)
    AkelPad.SetSel(nBrackPos, nBrackPos);
}

else if ((sAction == "r") && (nCarPos < nLastChar - 1))
{
  nBrackPos = nLastChar;
  for (i = 0; i < aClose.length; ++i)
  {
    nPos = sTxt.indexOf(aClose[i], nCarPos + 1);
    if ((nPos > -1) && (nPos < nBrackPos))
      nBrackPos = nPos;
  }
  if (nBrackPos < nLastChar)
    AkelPad.SetSel(nBrackPos, nBrackPos);
}

else if (sAction == "L")
{
  nBrack = ArraySearch(aOpen, sCarChar);

  if (nBrack < 0)
  {
    nBrackPos = -1;
    for (i = 0; i < aOpen.length; ++i)
    {
      nPos = sTxt.lastIndexOf(aOpen[i], nCarPos - 1);
      if (nPos > nBrackPos)
      {
        nBrackPos = nPos;
        nBrack    = i;
      }
    }
    if (nBrackPos > -1)
      nBegSel = nBrackPos + 1;
  }
  else
  {
    nBegSel = nCarPos;
    bSelAll = true;
  }

  if (nBrack > -1)
  {
    nBrackPos = sTxt.indexOf(aClose[nBrack], nCarPos + bSelAll);
    if (nBrackPos > -1)
    {
      if ((nBrackPos == nCarPos) && (! bSelAll))
      {
        --nBegSel;
        bSelAll = true;
      }
      nEndSel = (bSelAll) ? (nBrackPos + 1) : (nBrackPos);
      AkelPad.SetSel(nEndSel, nBegSel);
    }
  }
}

else if ((sAction == "R") && (nCarPos > 0))
{
  nBrack = ArraySearch(aClose, sCarChar);

  if (nBrack < 0)
  {
    nBrackPos = nLastChar;
    for (i = 0; i < aClose.length; ++i)
    {
      nPos = sTxt.indexOf(aClose[i], nCarPos + 1);
      if ((nPos > -1) && (nPos < nBrackPos))
      {
        nBrackPos = nPos;
        nBrack    = i;
      }
    }
    if (nBrackPos < nLastChar)
      nBegSel = nBrackPos;
  }
  else
  {
    nBegSel = nCarPos + 1;
    bSelAll = true;
  }

  if (nBrack > -1)
  {
    nBrackPos = sTxt.lastIndexOf(aOpen[nBrack], nCarPos - bSelAll);
    if (nBrackPos > -1)
    {
      if ((nBrackPos == nCarPos) && (! bSelAll))
      {
        ++nBegSel;
        bSelAll = true;
      }
      nEndSel = (bSelAll) ? (nBrackPos) : (nBrackPos + 1);
      AkelPad.SetSel(nEndSel, nBegSel);
    }
  }
}

function ArraySearch(aArray, sChar)
{
  var nPos = -1;
  var i;

  for (i = 0; i < aArray.length; ++i)
  {
    if (aArray[i] == sChar)
    {
      nPos = i;
      break;
    }
  }
  return nPos;
}

function GetOffset(hWnd, nFlag)
{
  var nOffset = -1;
  var lpIndex;

  if (lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/))
  {
    AkelPad.SystemFunction().Call("User32::SendMessage" + _TCHAR, hWnd, 3130 /*AEM_GETINDEX*/, nFlag, lpIndex);
    nOffset = AkelPad.SystemFunction().Call("User32::SendMessage" + _TCHAR, hWnd, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
    AkelPad.MemFree(lpIndex);
  }
  return nOffset;
}


Last edited by KDJ on Sat Aug 31, 2013 11:56 am; edited 2 times in total
Back to top
View user's profile Send private message
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Sat Nov 13, 2010 6:33 pm    Post subject: Reply with quote

Some my old (and not much Smile) scripts... Entire list here: akelpad_scripts.html
Note: some scripts are in beta stage...

toggleComments.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9924#9924
// http://infocatcher.ucoz.net/js/akelpad_scripts/toggleComments.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/toggleComments.js

// (c) Infocatcher 2008-2013
// version 0.4.3.2 - 2013-05-05

//===================
// Adds/removes comments

// Arguments:
//   -method=0                     - toggle (default)
//          =1                     - add
//          =2                     - remove
//   -addSpaces=true               - true => code /* comment */ code, false => code/*comment*/code
//   -removeSpaces=true
//   -preferLineComments=false     - true => don't use block comments for multiple lines
//   -lineCommentsAtStart=false
//   -checkBlockComments=0         - don't check block comments inside commented code
//                      =1         - ask user with default OK button
//                      =2         - (default) ask user with default Cancel button
//                      =3         - don't ask and don't add comments
//   -blockCommentsEntireLines=-1  - only if end EOL selected
//                            =0   - only if entire lines selected (with or without end EOL)
//                            =1   - always
//   -searchRegions=true           - allow search regions like <?php ... ?>
//   -checkSyntax=0                - don't check any syntax constructions, fast, but may works incorrect
//               =1                - check simple syntax constructions
//               =2                - (default) check complex syntax constructions (only in *.js for now), may be very slow
//   -saveLastExt=0                - don't save last used extension
//               =1                - save only typed (default)
//               =2                - always save

// For boolean arguments you can use
//   -argName       - true
//   -argName=true
//   -argName=false

// Usage:
//   Call("Scripts::Main", 1, "toggleComments.js")
//   Call("Scripts::Main", 1, "toggleComments.js", "-method=0 -addSpaces=false -preferLineComments=true")
//===================

//== Settings begin
// You can use toggleComments-options.js file for override or tweak commentsRegions and commentsSets
// Example of toggleComments-options.js file:
//   commentsSets.tpl = [ ["{*"], ["*}"], ["//"] ]; // Add new extension
//   // Change arguments defaults
//   addSpaces = getArg("addSpaces", false);
//   blockCommentsEntireLines = getArg("blockCommentsEntireLines", -1);
var commentsSets = {
   // Example:
   //   extension: [
   //       [blockCommentStart0, blockCommentStart1],
   //       [blockCommentEnd0, blockCommentEnd1],
   //       [lineComment]
   //   ]
   // Or "link" to already defined extension:
   //   otherExtension: "extension"
   // Use "null" (without commas) for unavailable comments type.
   // First string will be used for comments adding (blockCommentStart0 and blockCommentEnd0 in example).
   c: [ ["/*"], ["*/"], ["//"] ],
   cpp:  "c",
   h:    "c",
   js:   "c",
   jsm:  "c",
   java: "c",
   "..php..": [ ["/*"], ["*/"], ["//", "#"] ], // Reserved
   php: "..php..", // In case of -searchRegions=true we use html comments in *.php files and check <?php ... ?>
   dpr: [ ["{", "(*"], ["}", "*)"], ["//"] ],
   //pas: [ ["{", "(*"], ["}", "*)"], null ],
   pas: "dpr",
   html: [ ["<!--"], ["-->"], null ],
   xhtml: "html",
   shtml: "html",
   htm:   "html",
   xml:   "html",
   xsl:   "html",
   xul:   "html",
   xbl:   "html",
   rdf:   "html",
   dtd:   "html",
   css: [ ["/*"], ["*/"], null ],
   asm: [ null, null, [";"] ],
   ini: [ null, null, [";", "#"] ],
   bat: [ null, null, ["::", "rem "] ],
   vbs: [ null, null, ["'", "rem "] ],
   lss: [ ["%REM"], ["%END REM"], ["'"] ],
   manifest: [ null, null, ["#"] ],
   properties: [ null, null, ["#"] ],
   highlight: [ null, null, [";"] ],
   coder: [ null, null, [";"] ],
   sql: [ ["/*"], ["*/"], ["--"] ],
   htaccess: [ null, null, ["#"] ],
   //ahk: [ ["\r/*"], ["\r*/"], [";"] ],
   ahk: [ null, null, [";"] ],
   py: [ null, null, ["#"] ],
   pyw: "py"
};
var commentsRegions = {
   // Example:
   //   extension: {
   //       subExtension0: [[ext0_startMask0, ext0_endMask0], [ext0_startMask1, ext0_endMask1]],
   //       subExtension1: [[ext1_startMask0, ext1_endMask0]]
   //   }
   // Or "link" to already defined extension:
   //   otherExtension: "extension"
   // Masks is case unsensitive.
   html: {
      js: [["<script", "</script>"]],
      css: [["<style", "</style>"]],
      "..php..": [["<?php", "?>"], ["<?", "?>"]]
   },
   xhtml: "html",
   htm:   "html",
   php:   "html",
   xml: {
      css: [["<style", "</style>"]],
      "..php..": [["<?php", "?>"], ["<?", "?>"]],
      js: [
         ["<script", "</script>"],
         ["<![cdata[", "]]>"],
         ["<constructor>", "</constructor>"],
         ["<destructor>", "</destructor>"],
         ["<getter>", "</getter>"],
         ["<setter>", "</setter>"],
         ["<field", "</field>"],
         ["<method", "</method>"],
         ["<handler", "</handler>"]
      ]
   },
   xul: "xml",
   xbl: "xml"
};
var commentsExcludes = { // Now used only in delLineComments()
   // Special replacements for all extensions
   "..global..": function(str) {
      return str
         // Escape links like "http://example.com/"
         .replace(/([a-z-]):\/\/((\/*[^\/\s<>"*?&#\(\)\[\]\{\}]+)+)/g, "$1___$2")
         // Escaped slashes like "var re = /\//i;":
         .replace(/\\\//g, "__");
   },
   // Example:
   //   extension: function(str) { /* some operations with str */ return str; }
   // Or "link" to already defined extension:
   //   otherExtension: "extension"
   c: function(str) {
      if(oldRegExp)
         return str;
      // Remove strings ("..." and '...')
      return str
         .replace(/"(\\.|[^"\\\n\r])*"/g, escaper)
         .replace(/'(\\.|[^'\\\n\r])*'/g, escaper);
   },
   js: function(str) {
      if(oldRegExp)
         return str;
      // Remove strings ("..." and '...')
      str = str
         .replace(/"(\\.|[^"\\\n\r])*"/g, escaper)
         .replace(/'(\\.|[^'\\\n\r])*'/g, escaper);

      if(checkSyntax < 2)
         return str;

      // Try remove simple regular expressions like /x*/ and /\/*x/
      // We search for invalid divisions:
      // x = /./;            -> =
      // if(/a/.test(b))     -> (
      // x = [/a/, /b/]      -> [ ,
      // x = a && /b/test(c) -> & |
      // x = a ? /b/ : /c/   -> ? :
      // x = !/a/.test(b)    -> !
      return str.replace(
         /([=(\[,&|?:!]\s*((\/\/[^\n\r]*[\n\r]+|\/\*[\s\S]*?\*\/)\s*)*)\/([^*+?\\\/\n\r]|\\[^\n\r])(\\\/|[^\/\n\r])*\//g,
         // special chars   line comments       block comments         regexp begin                         regexp end
         function(s, prefix) {
            return prefix + escaper(s.substr(prefix.length));
         }
      );
   },
   jsm: "js",
   cpp:  "c",
   h:    "c",
   java: "c",
   php:  "c",
   dpr:  "c"
};
//== Settings end

function _localize(s) {
   var strings = {
      "Type extension of file:": {
         ru: "Введите расширение файла:"
      },
      "Settings for “%S” extension is missing!": {
         ru: "Настройки для расширения «%S» отсутствуют!"
      },
      "Invalid settings for “%S” extension!": {
         ru: "Неправильные настройки для расширения «%S»!"
      },
      " :: Comment": {
         ru: " :: Закомментировать"
      },
      " :: Uncomment": {
         ru: " :: Раскомментировать"
      },
      "Allow block comments inside?": {
         ru: "Разрешить блочные комментарии внутри?"
      },
      " :: Read only": {
         ru: " :: Только чтение"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var oSet = AkelPad.ScriptSettings();
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

var oldRegExp = "x".replace(/x/, function(s) { return "y" }) != "y";

// Read arguments:
// getArg(argName, defaultValue)
var method                   = getArg("method", 0);
var addSpaces                = getArg("addSpaces", true);
var removeSpaces             = getArg("removeSpaces", true);
var preferLineComments       = getArg("preferLineComments", false);
var lineCommentsAtStart      = getArg("lineCommentsAtStart", false);
var checkBlockComments       = getArg("checkBlockComments", 2);
var blockCommentsEntireLines = getArg("blockCommentsEntireLines", 1);
var searchRegions            = getArg("searchRegions", true);
var checkSyntax              = getArg("checkSyntax", 2);
var saveLastExt              = getArg("saveLastExt", 1);

// Support for old arguments
if(getArg("noSpaces") !== undefined && getArg("addSpaces") === undefined) {
   addSpaces = !getArg("noSpaces");
   if(getArg("removeSpaces") === undefined)
      removeSpaces = addSpaces;
}
if(getArg("multipleEnabled") !== undefined && getArg("searchRegions") === undefined)
   searchRegions = getArg("multipleEnabled");
//if(getArg("ignoreBlockCommentsInSel") !== undefined && getArg("checkBlockComments") === undefined)
//   checkBlockComments = 2;


if(searchRegions)
   commentsSets.php = commentsSets.html;

var optionsPath = WScript.ScriptFullName.replace(/(\.[^.]+)?$/, "-options$&");
if(new ActiveXObject("Scripting.FileSystemObject").FileExists(optionsPath))
   eval(AkelPad.ReadFile(optionsPath));

function Comments(opts) {
   for(var p in opts)
      this[p] = opts[p];
   this.space = this.addSpaces ? " " : "";
   this.init();
   this.defineExt(); // => this.currentExt
   this.initExt();
};
Comments.prototype = {
   toggleComments: function(method) {
      if(!method || method == 2) { // toggle or remove
         var insData = this.delComments();
         if(insData) // Comments deleted
            return insData;
         if(_stopMessages.length)
            return null;
      }
      if(!method || method == 1) // toggle or add
         return this.addComments();
      return null;
   },
   addComments: function() {
      return this.addLineComments()
         || this.addLinesComments()
         || this.addBlockComments();
   },
   delComments: function() {
      return this.delLineComments()
         || this.delLinesComments()
         || this.delBlockComments();
   },
   init: function() {
      this.selStart = AkelPad.GetSelStart();
      this.selEnd   = AkelPad.GetSelEnd();
      this.selText = AkelPad.GetSelText();

      //AkelPad.SetSel(0, -1);
      //this.fullText = AkelPad.GetSelText();
      this.fullText = AkelPad.GetTextRange(0, -1);
      //this.fullTextLen = this.fullText.length;

      this.startText = this.fullText.substring(0, this.selStart);
      this.endText = this.fullText.substring(this.selEnd);

      this.noSel = this.selStart == this.selEnd;
      this.isMultiline = !this.noSel && /[\n\r]/.test(this.selText);
   },
   defineExt: function() {
      this.currentExt = this.ext;
      if(!this.searchRegions)
         return;
      var mParams = this.getParams(this.cmmRegions, this.ext);
      var startText = this.startText.toLowerCase();
      var selText = this.selText.toLowerCase();
      var endText = this.endText.toLowerCase();
      var start, end;
      var startIndx, endIndx;
      var mParam;
      for(var ext in mParams) {
         mParam = mParams[ext];
         for(var i = 0, len = mParam.length; i < len; i++) {
            start = mParam[i][0];
            end = mParam[i][1];
            startIndx = endText.indexOf(start);
            endIndx = endText.indexOf(end);
            if(
               startText.lastIndexOf(start) > startText.lastIndexOf(end)
               && (selText.indexOf(start) == -1) && (selText.indexOf(end) == -1)
               && endIndx != -1
               && (startIndx == -1 || endIndx < startIndx)
            ) {
               this.currentExt = ext;
               return;
            }
         }
      }
   },
   initExt: function(cmmParams) {
      if(this._initialisedExt == this.currentExt)
         return;
      this._initialisedExt = this.currentExt;

      cmmParams = cmmParams || this.getParams(this.cmmSets, this.currentExt);

      this.cmmBlockStart = cmmParams[0];
      this.cmmBlockEnd   = cmmParams[1];
      this.cmmLine       = cmmParams[2];

      var buggyBlockStart = !this.isArray(this.cmmBlockStart);
      var buggyBlockEnd   = !this.isArray(this.cmmBlockEnd);
      var buggyLine       = !this.isArray(this.cmmLine);
      this.noCmmBlock = !this.cmmBlockStart || !this.cmmBlockEnd || buggyBlockStart || buggyBlockEnd;
      this.noCmmLine = !this.cmmLine || buggyLine;
      if(
         (this.cmmBlockStart && buggyBlockStart)
         || (this.cmmBlockEnd && buggyBlockEnd)
         || (this.cmmLine && buggyLine)
      )
         _addStopMessage(_localize("Invalid settings for “%S” extension!").replace("%S", this.currentExt));
   },
   getParams: function(sets, key) {
      var params = sets[key];
      if(typeof params == "string")
         params = sets[params];
      return params;
   },
   isArray: function(a) {
      return a instanceof Array;
   },
   exclude: function(str) {
      if(!checkSyntax)
         return str;
      var ex = this.cmmExcludes;
      if(ex["..global.."])
         str = ex["..global.."](str);
      var esc = this.getParams(ex, this.currentExt);
      if(esc)
         str = esc(str);
      return str;
   },
   delLineComments: function() {
      if(this.noCmmLine || this.isMultiline)
         return null;

      for(var i = 0, len = this.cmmLine.length; i < len; i++) {
         var cmmLine = this.cmmLine[i];

         var linePos = this.getBlockByIndex(this.selStart, this.selEnd);
         var lineStart = linePos[0];
         var lineEnd   = linePos[1];
         //AkelPad.SetSel(lineStart, lineEnd);
         //var line = AkelPad.GetSelText();
         var line = this.fullText.substring(lineStart, lineEnd);
         if(!this.noSel && this.selEnd < lineStart + line.indexOf(cmmLine))
            continue; // |     |   //

         var cmmLineIndx = this.exclude(line).indexOf(cmmLine);
         if(
            cmmLineIndx != -1
            && (
               this.selStart >= lineStart + cmmLineIndx // Caret should be after comment
               || /^[ \t]*$/.test(this.fullText.substring(lineStart, this.selStart)) // Or only spaces befor
            )
         ) {
            var linePart = line.substring(cmmLineIndx);
            //var sp = this.removeSpaces ? "[\\t ]?" : "";
            var sp = this.removeSpaces ? " ?" : "";
            var cmmLinePattern = this.escapeRegExp(cmmLine) + this.fixCmmLineRegExp(cmmLine);
            linePart = linePart.replace(new RegExp("^" + cmmLinePattern + sp), "");
            return {
               str: linePart,
               selBefore: [lineStart + cmmLineIndx, lineEnd],
               selAfter: [lineStart + cmmLineIndx, lineStart + cmmLineIndx + linePart.length]
            };
            //line = line.substring(0, cmmLineIndx) + linePart.replace(cmmLinePattern, "");
            //AkelPad.SetSel(lineStart, lineEnd);
            //AkelPad.ReplaceSel(line);
            //AkelPad.SetSel(lineStart + cmmLineIndx, lineStart + line.length);
         }
         //else
         //   continue;
         //return [lineStart + cmmLineIndx, lineStart + line.length]; //~~~
      }
      return null;
   },
   delLinesComments: function() {
      if(this.noCmmLine || !this.isMultiline)
         return null;

      cmmLoop:
      for(var i = 0, len = this.cmmLine.length; i < len; i++) {
         var cmmLine = this.cmmLine[i];

         var blockPos = this.getBlockByIndex(this.selStart, this.selEnd);

         //AkelPad.SetSel(blockPos[0], blockPos[1]);
         //var block = AkelPad.GetSelText();
         var block = this.fullText.substring(blockPos[0], blockPos[1]);
         var cmmLineEsc = this.escapeRegExp(cmmLine);
         var cmmLineEscFixed = cmmLineEsc + this.fixCmmLineRegExp(cmmLine);

         //if(!cmmLinePattern.test(block))
         //   continue;
         var removeSpaces = this.removeSpaces;
         var removeOnlyOneLevel = true;
         var hasLineCmmPattern = new RegExp("^[\\t ]*(" + cmmLineEscFixed + ")");
         var lines = this.exclude(block).split(/[\r\n]+/);
         var cmmLineLen = cmmLine.length;
         for(var j = 0, l = lines.length; j < l; j++) {
            if(!hasLineCmmPattern.test(lines[j]))
               continue cmmLoop;
            var cmmChrs = RegExp.$1;
            if(removeSpaces && /^\S/.test(RegExp.rightContext))
               removeSpaces = false;
            if(
               removeOnlyOneLevel
               && cmmChrs.length > cmmLineLen
               && !hasLineCmmPattern.test(cmmChrs.substr(cmmLineLen))
            )
               removeOnlyOneLevel = false;
         }

         var lineCmmPattern = new RegExp(
            "(^|\\r\\n|\\n|\\r)([\\t ]*)"
               + (removeOnlyOneLevel ? cmmLineEsc : cmmLineEscFixed)
               //+ this.fixCmmLineRegExp(cmmLine)
               + (removeSpaces ? " ?" : ""),
            "g"
         );
         block = block.replace(lineCmmPattern, "$1$2");

         //AkelPad.SetSel(blockPos[0], blockPos[1]);
         //AkelPad.ReplaceSel(block);
         //AkelPad.SetSel(blockPos[0], blockPos[0] + block.length);
         //return [blockPos[0], blockPos[0] + block.length];
         return {
            str: block,
            selBefore: [blockPos[0], blockPos[1]],
            selAfter: [blockPos[0], blockPos[0] + block.length]
         };
      }
      return null;
   },
   delBlockComments: function() {
      if(this.noCmmBlock)
         return null;

      for(var i = 0, len = this.cmmBlockStart.length; i < len; i++) {
         var cmmBlockStart = this.cmmBlockStart[i];
         var cmmBlockEnd = this.cmmBlockEnd[i];

         if(!cmmBlockStart || !cmmBlockEnd) {
            _addStopMessage(_localize("Invalid settings for “%S” extension!").replace("%S", this.currentExt));
            continue;
         }

         //       selection
         // 0  /* |       | */
         // 1  /* | */    |
         // 2     |    /* | */
         // 3     | /* */ |

         // noSel && noCmmLine
         // 4  /* */ |
         // 5        | /* */

         var startPos, endPos;

         var cmmLen = Math.max(cmmBlockStart.length, cmmBlockEnd.length);
         var add = cmmLen - 1;

         var fullText = this.exclude(this.fullText);

         var ss = this.selStart;
         var se = this.selEnd;

         var startTextAdd    = fullText.substring(0, ss + add);
         var startSelTextAdd = fullText.substring(0, se + add);
         var selTextAdd      = fullText.substring(ss - add, se + add);
         var selEndTextAdd   = fullText.substring(ss - add);
         var endTextAdd      = fullText.substring(se - add);

         var selOpenIndx  = selTextAdd.indexOf(cmmBlockStart);
         var selCloseLastIndx = selTextAdd.lastIndexOf(cmmBlockEnd);

         if(selOpenIndx == -1 && selCloseLastIndx == -1) { // 0  /* |       | */
            var startOpenLastIndx  = startTextAdd.lastIndexOf(cmmBlockStart); // /* |  |
            var startCloseLastIndx = startTextAdd.lastIndexOf(cmmBlockEnd);   // */ |  |
            var endOpenIndx        = endTextAdd.indexOf(cmmBlockStart);       //    |  | /*
            var endCloseIndx       = endTextAdd.indexOf(cmmBlockEnd);         //    |  | */
            if(Math.max(startOpenLastIndx, startCloseLastIndx, endOpenIndx, endCloseIndx) == -1) // Not found
               continue;
            if(
               startOpenLastIndx != -1 && startOpenLastIndx > startCloseLastIndx // */ /* |  |
               && endCloseIndx != -1 && (endOpenIndx == -1 || endCloseIndx < endOpenIndx) // |  | */ /*
            ) {
               startPos = startOpenLastIndx;
               endPos = Math.max(0, se - add) + endCloseIndx + cmmBlockEnd.length;
            }
            // noSel && noCmmLine
            // 4  /*  */  |
            // 5          |  /*  */
            if(
               startPos == undefined && endPos == undefined
               && this.noSel && this.noCmmLine
            ) {
               // 4  /*  */  |
               var linePos = this.getLineByIndex(ss);
               //var line = fullText.substring(linePos[0], linePos[1]);

               var lineStartAdd = fullText.substring(linePos[0], ss + add);

               var lineStartOpenIndx      = lineStartAdd.indexOf(cmmBlockStart);
               var lineStartOpenLastIndx  = lineStartAdd.lastIndexOf(cmmBlockStart);
               var lineStartCloseIndx     = lineStartAdd.indexOf(cmmBlockEnd);
               var lineStartCloseLastIndx = lineStartAdd.lastIndexOf(cmmBlockEnd);
               if(
                  lineStartOpenLastIndx != -1 && lineStartCloseLastIndx != -1
                  && lineStartOpenLastIndx < lineStartCloseLastIndx  // Detect */ /* |
               ) {
                  var commented = fullText.substring( // Check for /* or */ inside
                     linePos[0] + lineStartOpenLastIndx + cmmBlockStart.length,
                     linePos[0] + lineStartCloseLastIndx
                  );
                  if(commented.indexOf(cmmBlockStart) == -1 && commented.indexOf(cmmBlockEnd) == -1) {
                     startPos = linePos[0] + lineStartOpenLastIndx;
                     endPos   = linePos[0] + lineStartCloseLastIndx + cmmBlockEnd.length;
                  }
               }
               if(startPos == undefined && endPos == undefined) {
                  // 5          |  /*  */
                  var lineEndAdd = fullText.substring(ss - add, linePos[1]);

                  var lineEndOpenIndx      = lineEndAdd.indexOf(cmmBlockStart);
                  var lineEndOpenLastIndx  = lineEndAdd.lastIndexOf(cmmBlockStart);
                  var lineEndCloseIndx     = lineEndAdd.indexOf(cmmBlockEnd);
                  var lineEndCloseLastIndx = lineEndAdd.lastIndexOf(cmmBlockEnd);
                  if(
                     lineEndOpenIndx != -1 && lineEndCloseIndx != -1
                     && lineEndOpenIndx < lineEndCloseIndx // Detect | */ /*
                  ) {
                     var lineEndOffset = Math.max(0, ss - add);
                     var commented = fullText.substring( // Check for /* or */ inside
                        lineEndOffset + lineEndOpenIndx + cmmBlockStart.length,
                        lineEndOffset + lineEndCloseIndx
                     );
                     if(commented.indexOf(cmmBlockStart) == -1 && commented.indexOf(cmmBlockEnd) == -1) {
                        startPos = lineEndOffset + lineEndOpenIndx;
                        endPos   = lineEndOffset + lineEndCloseIndx + cmmBlockEnd.length;
                     }
                  }
               }
            }
         }
         else if(selOpenIndx == -1 && selCloseLastIndx != -1) { // 1  /* | */    |
            var selCloseIndx = selTextAdd.indexOf(cmmBlockEnd); // Check for | */ */ |
            if(selCloseIndx == selCloseLastIndx) {
               var startOpenLastIndx  = startTextAdd.lastIndexOf(cmmBlockStart); // /*    | */ |
               var startCloseLastIndx = startTextAdd.lastIndexOf(cmmBlockEnd);   // /* */ | */ |
               selCloseIndx += Math.max(0, ss - add);
               if(
                  startOpenLastIndx != -1
                  && (
                     startCloseLastIndx < startOpenLastIndx // */ /* | */ |
                     || selCloseIndx == startCloseLastIndx  // +add => can be same
                  )
               ) {
                  startPos = startOpenLastIndx;
                  endPos = selCloseIndx + cmmBlockEnd.length;
               }
            }
         }
         else if(selOpenIndx != -1 && selCloseLastIndx == -1) { // 2     |    /* | */
            var selOpenLastIndx = selTextAdd.lastIndexOf(cmmBlockStart); // Check for | /* /* |
            if(selOpenIndx == selOpenLastIndx) {
               var endCloseIndx = endTextAdd.indexOf(cmmBlockEnd);  // | /* |    */
               var endOpenIndx = endTextAdd.indexOf(cmmBlockStart); // | /* | /* */
               selOpenIndx += Math.max(0, ss - add);
               if(
                  endCloseIndx != -1
                  && (
                     endOpenIndx == -1 || endCloseIndx < endOpenIndx // /* | */ /*
                     || selOpenIndx == Math.max(0, se - add) + endOpenIndx // +add => can be same
                  )
               ) {
                  startPos = selOpenIndx;
                  endPos = Math.max(0, se - add) + endCloseIndx + cmmBlockEnd.length;
               }
            }
         }
         //if(selOpenIndx != -1 && selCloseLastIndx != -1) {
         else { // 3     | /* */ |
            if(!this.noCmmLine && this.isMultiline && this.pLineCmm) {
               // Check for |/* */|
               var tmp = fullText.substring(ss, se)
                  .replace(/^\s+|\s+$/g, "");
               if(
                  tmp.substr(0, cmmBlockStart.length) != cmmBlockStart
                  || tmp.slice(-cmmBlockEnd.length) != cmmBlockEnd
               )
                  continue;
            }

            // Allow remove any selected comments: | /* ... */ |
            var selCloseIndx    = selTextAdd.indexOf(cmmBlockEnd);       // | */ /* */    |
            var selOpenLastIndx = selTextAdd.lastIndexOf(cmmBlockStart); // |    /* */ /* |
            if(
               (selCloseIndx == -1 || selOpenIndx < selCloseIndx)
               && selCloseLastIndx > selOpenLastIndx
            ) {
               var selOffset = Math.max(0, ss - add);
               startPos = selOffset + selOpenIndx;
               endPos   = selOffset + selCloseLastIndx + cmmBlockEnd.length;
            }
         }

         if(startPos == undefined || endPos == undefined)
            continue;

         //WScript.Echo(startPos +"\n"+ endPos);
         //AkelPad.SetSel(startPos, endPos);
         //return [startPos, endPos];

         var startPosIns = startPos;
         var endPosIns   = endPos;

         var openPattern = this.escapeRegExp(cmmBlockStart) + this.fixCmmBlockStartRegExp(cmmBlockStart);
         var closePattern = this.fixCmmBlockEndRegExp(cmmBlockEnd) + this.escapeRegExp(cmmBlockEnd);
         var spPattern = this.removeSpaces ? " ?" : "";

         var startLinePos = this.getLineByIndex(startPos);
         var endLinePos   = this.getLineByIndex(endPos, startLinePos[0]);
         var startLine = this.fullText.substring(startLinePos[0], startLinePos[1]);
         var endLine   = this.fullText.substring(endLinePos[0], endLinePos[1]);
         if(new RegExp("^[ \\t]*" + openPattern + "[ \\t]*$").test(startLine)) { // Only /* in line
            startPosIns = startLinePos[0];
            openPattern = "[ \\t]*" + openPattern + "[ \\t]*(\\n\\r?|\\r\\n?)";
         }
         else
            openPattern += spPattern;
         if(new RegExp("^[ \\t]*" + closePattern + "[ \\t]*$").test(endLine)) { // Only */ in line
            endPosIns = endLinePos[1];
            closePattern = "(\\n\\r?|\\r\\n?)[ \\t]*" + closePattern + "[ \\t]*";
         }
         else
            closePattern = spPattern + closePattern;

         var ins = this.fullText.substring(startPosIns, endPosIns)
            .replace(new RegExp("^" + openPattern + closePattern + "$"), "") // Simple way to remove /****/
            .replace(new RegExp("^" + openPattern), "")
            .replace(new RegExp(closePattern + "$"), "");

         if(!this.checkBlockComments(ins, cmmBlockStart, cmmBlockEnd, false))
            continue;

         this.getBlockByIndex(ss, se); // Set this._hasEmptyLine

         return {
            str: ins,
            selBefore: [startPosIns, endPosIns],
            selAfter: [startPosIns, startPosIns + ins.length]
         };
      }
      return null;
   },
   addLineComments: function() {
      if(this.noCmmLine || (!this.noSel && !this.noCmmBlock) || this.isMultiline)
         return null;

      var cmmLine = this.cmmLine[0];

      var linePos = this.getLineByIndex(this.selStart);
      var line = this.fullText.substring(linePos[0], linePos[1]);
      var startPos = this.noSel
         ? linePos[0] + line.match(/^[\t ]*/)[0].length
         : this.selStart;
      //AkelPad.SetSel(startPos, linePos[1]);
      //var endText = AkelPad.GetSelText();
      var endText = this.fullText.substring(startPos, linePos[1]);
      var cmm = (
         this.noSel
            ? ""
            : /[ \t]/.test(this.fullText.charAt(startPos - 1))
               ? ""
               : this.space
         )
         + cmmLine
         + (/ $/.test(cmmLine) ? "" : this.space);
      var ins = cmm + endText;
      //AkelPad.SetSel(startPos, linePos[1]);
      //AkelPad.ReplaceSel(ins);

      var startAdd = 0;
      var posAdd = 0;
      if(!endText)
         startAdd = cmm.length;
      else
         posAdd = ins.length;
      //AkelPad.SetSel(startPos, startPos + posAdd);
      //return [startPos, startPos + posAdd];
      return {
         str: ins,
         selBefore: [startPos, linePos[1]],
         selAfter: [startPos + startAdd, startPos + startAdd + posAdd]
      };
   },
   addLinesComments: function() {
      if(this.noCmmLine || !this.isMultiline || (!this.pLineCmm && !this.noCmmBlock))
         return null;

      var blockPos = this.getBlockByIndex(this.selStart, this.selEnd);
      if(
         !this.noCmmBlock
         && this.blockCmmsEntireLines < 1
         && (
            blockPos[0] != this.selStart
            || !(
               blockPos[1] == this.selEnd
               || blockPos[1] == this.selEnd - 1 && this._getLineByIndex(this.selEnd)[0] == this.selEnd
            )
         )
      )
         return null;

      var cmmLine = this.cmmLine[0];

      //AkelPad.SetSel(blockPos[0], blockPos[1]);
      //var block = AkelPad.GetSelText();
      var block = this.fullText.substring(blockPos[0], blockPos[1]);

      var lines = block.split("\r");
      var linesCnt = lines.length;
      var spacePrefix = "";
      var spacePrefixLen;

      //var hasLineCmmPattern = new RegExp("(^|\\r\\n|\\n|\\r)([\\t ]*)" + this.escapeRegExp(cmmLine));
      //var atStart = hasLineCmmPattern.test(this.exclude(block))
      //   ? true
      //   : this.lineCmmAtStart;

      if(!this.lineCmmAtStart) {
         var minSpLen = Infinity;
         for(var i = 0; i < linesCnt; i++) {
            var line = lines[i];
            if(/^[ \t]*$/.test(line))
               continue;
            if(!/^[ \t]+/.test(line)) {
               spacePrefix = "";
               break;
            }
            var sp = RegExp.lastMatch;
            if(sp.length < minSpLen) {
               minSpLen = sp.length;
               spacePrefix = sp;
            }
         }
         if(spacePrefix) {
            spacePrefixLen = spacePrefix.length;
            for(var i = 0; i < linesCnt; i++) {
               var line = lines[i];
               if(!line)
                  continue;
               if(
                  /^[ \t]+$/.test(line) && line.length < spacePrefixLen
                     ? spacePrefix.substr(0, line.length) != line
                     : line.substr(0, spacePrefixLen) != spacePrefix
               ) {
                  spacePrefix = "";
                  break;
               }
            }
         }
      }

      spacePrefixLen = spacePrefix.length;
      var cmmAdd = cmmLine + (/ $/.test(cmmLine) ? "" : this.space);

      for(var i = 0; i < linesCnt; i++)
         lines[i] = spacePrefix + cmmAdd + lines[i].substr(spacePrefixLen);

      block = lines.join("\n");

      //AkelPad.SetSel(blockPos[0], blockPos[1]);
      //AkelPad.ReplaceSel(block);
      //AkelPad.SetSel(blockPos[0], blockPos[0] + block.length);
      //return [blockPos[0], blockPos[0] + block.length];
      return {
         str: block,
         selBefore: [blockPos[0], blockPos[1]],
         selAfter: [blockPos[0], blockPos[0] + block.length]
      };
   },
   addBlockComments: function() {
      if(this.noCmmBlock)
         return null;

      var cmmBlockStart = this.cmmBlockStart[0];
      var cmmBlockEnd = this.cmmBlockEnd[0];

      var startLinePos = this.getLineByIndex(this.selStart);

      if(!this.isMultiline && this.noSel && this.noCmmLine) { // Comment current line
         var line = this.fullText.substring(startLinePos[0], startLinePos[1]);
         var start = line.search(/\S/);
         if(start == -1) // empty line
            start = this.selStart - startLinePos[0];
         line = line.replace(/^\s+|\s+$/g, "");
         var startPos = startLinePos[0] + start;
         //AkelPad.SetSel(startPos, startPos + line.length);

         var cmmStart = cmmBlockStart + this.space;
         var cmmEnd = this.space + cmmBlockEnd;

         if(!this.checkBlockComments(line, cmmBlockStart, cmmBlockEnd, true))
            return null;
         var ins = cmmStart + line + cmmEnd;
         //AkelPad.ReplaceSel(ins);

         var startAdd = 0;
         var posAdd = 0;
         if(!line) // " /*  */ "
            startAdd = cmmStart.length;
         else
            posAdd = ins.length;
         //AkelPad.SetSel(startPos, startPos + posAdd);
         //return [startPos, startPos + posAdd];
         return {
            str: ins,
            selBefore: [startPos, startPos + line.length],
            selAfter: [startPos + startAdd, startPos + startAdd + posAdd]
         };
      }

      var endLinePos = this.getLineByIndex(this.selEnd, startLinePos[0]);

      if(this.blockCmmsEntireLines < 1)
         var entireLinesSelected = startLinePos[0] == this.selStart
            && (
               this.blockCmmsEntireLines == 0 && endLinePos[1] == this.selEnd
               || endLinePos[1] == this.selEnd - 1 && this.getLineByIndex(this.selEnd)[0] == this.selEnd
            );

      if(!this.isMultiline || this.blockCmmsEntireLines < 1 && !entireLinesSelected) {
         var _startText = this.fullText.substring(startLinePos[0], this.selStart);
         var _endText = this.fullText.substring(this.selEnd, endLinePos[1]);
         var cmmStart = (/[\t ]$|^$/.test(_startText) ? "" : this.space)
            + cmmBlockStart
            + (/^[\t ]|^$/.test(this.selText) ? "" : this.space);
         var cmmEnd = (/[\t ]$|^$/.test(this.selText) ? "" : this.space)
            + cmmBlockEnd
            + (/^[\t ]|^$/.test(_endText) ? "" : this.space);
         if(!this.checkBlockComments(this.selText, cmmBlockStart, cmmBlockEnd, true))
            return null;
         var _text = cmmStart + this.selText + cmmEnd;
         //AkelPad.SetSel(startLinePos[0], startLinePos[1]);
         //AkelPad.ReplaceSel(_startText + _text + _endText);
         //AkelPad.SetSel(this.selStart, this.selEnd);
         //AkelPad.ReplaceSel(_text);
         //AkelPad.SetSel(this.selStart, this.selStart + _text.length);
         //return [this.selStart, this.selStart + _text.length];
         return {
            str: _text,
            selBefore: [this.selStart, this.selEnd],
            selAfter: [this.selStart, this.selStart + _text.length]
         };
      }

      var _startLine = this.fullText.substring(startLinePos[0], startLinePos[1]);
      var _endLine = this.fullText.substring(endLinePos[0], endLinePos[1]);
      var _startLineSp = _startLine.match(/^[\t ]*/)[0];
      var _endLineSp = _endLine.match(/^[\t ]*/)[0];
      var sp = _startLineSp.length < _endLineSp.length ? _startLineSp : _endLineSp;

      //AkelPad.SetSel(startLinePos[0], endLinePos[1]);
      //var block = AkelPad.GetSelText();
      var block = this.fullText.substring(startLinePos[0], endLinePos[1]);
      if(!this.checkBlockComments(block, cmmBlockStart, cmmBlockEnd, true))
         return null;
      block = sp + cmmBlockStart + "\n"
         + block
         + "\n" + sp + cmmBlockEnd;
      //AkelPad.ReplaceSel(block);
      //AkelPad.SetSel(startLinePos[0], startLinePos[0] + block.length);
      //return [startLinePos[0], startLinePos[0] + block.length];
      return {
         str: block,
         selBefore: [startLinePos[0], endLinePos[1]],
         selAfter: [startLinePos[0], startLinePos[0] + block.length]
      };
   },
   checkBlockComments: function(str, cmmBlockStart, cmmBlockEnd, add) {
      if(!this.checkBlockCmms)
         return true;
      str = this.exclude(str);
      if(str.indexOf(cmmBlockStart) != -1 || str.indexOf(cmmBlockEnd) != -1) {
         if(this.checkBlockCmms == 1 || this.checkBlockCmms == 2)
            return AkelPad.MessageBox(
               hMainWnd,
               _localize("Allow block comments inside?"),
               dialogTitle + _localize(add ? " :: Comment" : " :: Uncomment"),
               33 /*MB_OKCANCEL|MB_ICONQUESTION*/
                  | (this.checkBlockCmms == 1 ? 0 /*MB_DEFBUTTON1*/ : 256 /*MB_DEFBUTTON2*/)
            ) == 1 /*IDOK*/;
         return false;
      }
      return true;
   },
   /***
   getBlockByIndex: function(startIndx, endIndx) {
      var middleLen = endIndx - startIndx;
      var start = this.fullText.substring(0, startIndx);
      var lineStart = start.search(/(^|\r\n|\n|\r)[^\n\r]*$/);
      lineStart += RegExp.$1.length;
      var end = this.fullText.substring(endIndx);
      var lineEnd = start.length + middleLen + end.search(/\r|\n|$/);
      return [lineStart, lineEnd];
   },
   ***/
   getBlockByIndex: function(startIndx, endIndx) {
      // Based on Instructor's code
      // http://akelpad.sourceforge.net/forum/viewtopic.php?p=11382#11382
      var line1Start = this.getOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, startIndx);
      var line2Start = this.getOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, endIndx);
      var line2End   = this.getOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/,   endIndx);
      if(line2Start != line1Start && line2Start == endIndx) {
         line2End = line2Start - 1;
         var hasEmptyLine = true;
      }
      this._hasEmptyLine = hasEmptyLine;
      return [line1Start, line2End];
   },
   getLineByIndex: function(indx, prevLineStart, ignoreEmptyLine) {
      // Based on Instructor's code
      // http://akelpad.sourceforge.net/forum/viewtopic.php?p=11382#11382
      //return this.getBlockByIndex(indx, indx);
      var lineStart = this.getOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, indx);
      if(prevLineStart != undefined && lineStart != prevLineStart && lineStart == indx) {
         lineStart = this.getOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, --indx);
         var hasEmptyLine = true;
      }
      if(!ignoreEmptyLine)
         this._hasEmptyLine = hasEmptyLine;
      var lineEnd = this.getOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/, indx);
      return [lineStart, lineEnd];
   },
   _getLineByIndex: function(indx, prevLineStart) {
      return this.getLineByIndex(indx, prevLineStart, true);
   },
   getOffset: function(hWndEdit, nType /*AEGI_*/, nOffset) {
      // Based on Instructor's code
      // http://akelpad.sourceforge.net/forum/viewtopic.php?p=11382#11382
      var lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
      if(!lpIndex)
         return 0;
      if(nOffset != -1)
         AkelPad.SendMessage(hWndEdit, 3137 /*AEM_RICHOFFSETTOINDEX*/, nOffset, lpIndex);
      AkelPad.SendMessage(hWndEdit, 3130 /*AEM_GETINDEX*/, nType, lpIndex);
      nOffset = AkelPad.SendMessage(hWndEdit, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
      AkelPad.MemFree(lpIndex);
      return nOffset;
   },
   escapeRegExp: function(str) {
      return str.replace(/[\\.^$+*?|()\[\]{}]/g, "\\$&");
   },
   fixCmmLineRegExp: function(cmmLine) {
      if(cmmLine == "//")
         return "/*[~=]*";
      return this.escapeRegExp(cmmLine.charAt(cmmLine.length - 1)) + "*";
   },
   fixCmmBlockStartRegExp: function(cmmBlockStart) {
      return this.escapeRegExp(cmmBlockStart.charAt(cmmBlockStart.length - 1)) + "*";
   },
   fixCmmBlockEndRegExp: function(cmmBlockEnd) {
      return this.escapeRegExp(cmmBlockEnd.charAt(0)) + "*";
   }
};

var _stopMessages = [];
function _addStopMessage(msg) {
   _stopMessages[_stopMessages.length] = msg;
}

if(hMainWnd) {
   parseContent(method);
   if(_stopMessages.length)
      AkelPad.MessageBox(hMainWnd, _stopMessages.join("\n\n"), dialogTitle, 48 /*MB_ICONEXCLAMATION*/);
}

function parseContent(method) {
   var params = getCurrentExt();
   if(!params)
      return;
   var ext = params[0];
   var cmmParams = params[1];
   if(!cmmParams)
      return;
   var comments = new Comments({
      ext:                  ext,
      cmmSets:              commentsSets,
      cmmRegions:           commentsRegions,
      cmmExcludes:          commentsExcludes,
      //selParams:            selParams,
      addSpaces:            addSpaces,
      removeSpaces:         removeSpaces,
      searchRegions:        searchRegions,
      checkBlockCmms:       checkBlockComments,
      blockCmmsEntireLines: blockCommentsEntireLines,
      pLineCmm:             preferLineComments,
      lineCmmAtStart:       lineCommentsAtStart
   });
   var insData = comments.toggleComments(method);
   if(!insData)
      return;
   if(comments._hasEmptyLine) {
      insData.selBefore[1] += 1;
      insData.selAfter[1] += 1;
      // Here should be "\n", but following code is safer
      insData.str += AkelPad.GetTextRange(insData.selBefore[1] - 1, insData.selBefore[1]);
   }
   var ro = AkelPad.GetEditReadOnly(hWndEdit);
   insertNoScroll(insData.str, insData.selBefore, ro ? null : insData.selAfter);
   ro && AkelPad.MessageBox(hMainWnd, insData.str, dialogTitle + _localize(" :: Read only"), 64 /*MB_ICONINFORMATION*/);
}
function insertNoScroll(str, selBefore, selAfter) {
   //~ todo: save horizontal scroll?
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return;
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   selBefore && AkelPad.SetSel(selBefore[0], selBefore[1]);
   AkelPad.ReplaceSel(str);
   selAfter && AkelPad.SetSel(selAfter[0], selAfter[1]);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   setRedraw(hWndEdit, true);
   AkelPad.MemFree(lpPoint);
}

function getCurrentExt() {
   var ext;
   var cFile = AkelPad.GetEditFile(0);
   if(cFile && /\.([^.]+)$/i.test(cFile)) {
      ext = RegExp.$1.toLowerCase(); // js, css, etc.
      if(ext && !commentsSets[ext])
         ext = null;
   }
   var read, write;
   if(saveLastExt && (read = oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))) {
      var extCacheId = "processId:" + oSys.Call("kernel32::GetCurrentProcessId")
         + "|hMainWnd:" + hMainWnd
         + "|hInstanceDll:" + AkelPad.GetInstanceDll()
         + "|hInstanceExe:" + AkelPad.GetInstanceExe();
      var extCacheExpired = oSet.Read("extCacheToken", 3 /*PO_STRING*/) != extCacheId;
   }
   if(!ext) {
      if(saveLastExt && read && !extCacheExpired) {
         var extCache = oSet.Read("extCache", 3 /*PO_STRING*/) || "";
         if(extCache && new RegExp("(^|\|)" + hWndEdit + "=([^|]+)").test(extCache))
            ext = RegExp.$2;
      }
      if(!ext) {
         var extTyped = true;
         ext = AkelPad.InputBox(
            hMainWnd,
            dialogTitle,
            _localize("Type extension of file:"),
            saveLastExt
               && (read || (read = oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/)))
               && oSet.Read("lastExt", 3 /*PO_STRING*/)
               || ""
         );
      }
   }
   read && oSet.End();
   if(!ext)
      return null;
   ext = ext.toLowerCase();
   var cmmSet = commentsSets[ext];
   if(typeof cmmSet == "string")
      cmmSet = commentsSets[cmmSet];
   if(!cmmSet)
      _addStopMessage(_localize("Settings for “%S” extension is missing!").replace("%S", ext));
   else if(saveLastExt) {
      if((extTyped || saveLastExt == 2) && (write = oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/)))
         oSet.Write("lastExt", 3 /*PO_STRING*/, ext);
      if(extTyped && (write || (write = oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/)))) {
         extCache = (extCache || "").split("|");
         while(extCache.length > 99)
            extCache.shift();
         extCache = extCache.join("|");
         extCache += (extCache ? "|" : "") + hWndEdit + "=" + ext;
         oSet.Write("extCache", 3 /*PO_STRING*/, extCache);
         oSet.Write("extCacheToken", 3 /*PO_STRING*/, extCacheId);
         var saved = true;
      }
   }
   if(extCacheExpired && !saved && (write || (write = oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/)))) {
      oSet.Delete("extCache");
      oSet.Delete("extCacheToken");
   }
   write && oSet.End();
   return [ext, cmmSet];
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getArg(argName, defaultVal) {
   var args = {};
   for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
      if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
         args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
   getArg = function(argName, defaultVal) {
      argName = argName.toLowerCase();
      return typeof args[argName] == "undefined" // argName in args
         ? defaultVal
         : args[argName];
   };
   return getArg(argName, defaultVal);
}
function escaper(str) {
   return new Array(str.length + 1).join("_");
}
<download | mirror | development version>


Last edited by Infocatcher on Sun May 05, 2013 1:21 pm; edited 15 times in total
Back to top
View user's profile Send private message
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Sat Nov 13, 2010 6:41 pm    Post subject: Reply with quote

punctuationFixer.js
Code:
// (c) Infocatcher 2008-2009
// version 0.0.3.0+ - 2009-09-24, 2010-07-05

//== Settings
var fixerDash = "\u2013";
var fixerForceUpperCase = true;
// Use
// Call("Scripts::Main", 1, "punctuationFixer.js", "-ignorecase", 0)
// for override this setting
var fixerCommas = ["«", "»"]; // var fixerCommas = null;
var fixerSaveSelPos = true;
//== End of settings

if(WScript.Arguments.length && WScript.Arguments(0) == "-ignorecase")
   fixerForceUpperCase = false;

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

var PunctuationFixer = function(dash, forceUpper, commas) {
   this.dash = dash || "-";
   this.forceUpper = forceUpper;
   this.convCommas = commas instanceof Array;
   if(this.convCommas) {
      this.openComma = commas[0];
      this.closeComma = commas[1];
   }
};
PunctuationFixer.prototype = {
   notConv: [],
   subst: "",
   init: function() { // Get random string for replacing exclusions
      function rnd() { return Math.random().toString().replace(/\./, ""); }
      this.subst = "_" + rnd() + rnd() + "_";
   },
   getSubst: function(n) {
      return this.subst + n + "_";
   },
   convert: function(txt) {
      if(!txt)
         return "";
      this.init();

      var _this = this;

      //== Exclusions:
      var excCnt = -1;
      var subst;
      // URLs like http://example.com/
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /[a-z]+:\/\/+([^\/\\.\s'"<>]+[.\/])+[^\/\\.\s'"<>]+/ig,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[0]);
            return subst;
         }
      );
      // Time "10:43:01"
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /(^|\D)([0-2]?\d:[0-6]?\d(:[0-6]?\d)?)(\D|$)/mg,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[2]);
            return a[1] + subst + a[4];
         }
      );
      // Dates "19.03.2009"
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /(^|\D)([0-3]?\d\.[0-1]\d\.\d\d(\d\d)?|\d\d(\d\d)?\.[0-1]\d\.[0-3]?\d)(\D|$)/mg,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[2]);
            return a[1] + subst + a[5];
         }
      );
      // Numbers like "10.9" or "10,9"
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /(^|[^\d.,])(\d+[.,]\d+)([^\d.,]|$)/g,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[2]);
            return a[1] + subst + a[3];
         }
      );
      // Smileys like ":)"
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /[ \t]*(:-?[D\(\)\\\/][\(\)]{0,2})[\(\)]*[ \t]*/g,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(" " + a[1] + " ");
            return subst;
         }
      );
      // "->", "=>", "<=>"
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /<?[-=]+>/g,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[0]);
            return subst;
         }
      );
      // Acronyms
      this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
      txt = txt.replace(
         /([^а-яёa-z]([а-яёa-z]\.[ \t]*[а-яёa-z]\.|[а-яёa-z]{2}\.))/g,
         function() {
            var a = arguments;
            _this.notConv[excCnt].push(a[1].replace(/[ \t]+/, " "));
            return subst;
         }
      );
      //== End of exclusions

      // Del spaces:
      txt = txt.replace(/(\S)([ \t])[ \t]+/g, "$1$2"); // "\t  " -> "\t", " \t\t" -> " "

      // Fix punctuation:
      txt = txt
         .replace(/((\) ?){1,3})(\) ?)*/g, "$1 ")   // ")))))" -> ")))"
         .replace(/[\t ]*([.?!][^"])/g, "$1 ") // "  !  !  !  " -> "! ! ! "
         .replace(/[\t ]*([:,;])[\t ]*/g, "$1 ") // " , " -> ", "
         .replace(/([,;:]) ?([,;:] ?)+/g, "$1 ")    // ",, ,, " -> ", "
         .replace(
            /(([.?!] *){1,3})([.?!] *)*(.|$)/mg, // "! !! ! " -> "!!! "
            function($0, $1, $2, $3, $4) {
               var noSp = $3 && /\S$/.test($3) && $4 == '"';
               return $1.replace(/\s+/g, "") + (noSp ? "" : " ") + $4;
            }
         )
         .replace(/([\(\{\[<])[\t ]+/, "$1")
         .replace(/[\t ]+([\)\}\]>])/, "$1")
         .replace(/[\t ]*([+=])[\t ]*/g, " $1 ");

      // Fix brackets:
      txt = txt
         .replace(/(\S)[\t ]*\([\t ]*/g, "$1 (")  // text(text -> text (text
         .replace(/[\t ]*\)[\t ]*([^.!?:;,()])/g, ") $1"); // text)text -> text) text

      // Fix lower case letters:
      if(this.forceUpper) // end. begin -> end. Begin
         txt = txt.replace(
            /(^|[^.][.?!] )([а-яёa-z])/mg,
            function($0, $1, $2) { return $1 + $2.toUpperCase(); }
         );

      // Fix dashes:
      txt = txt // " -", "- " -> " - "
         .replace(/"[\t ]*-[\t ]*/g, "\" - ") // text"-text -> text" - text
         .replace(/([^\s-])[\t ]*-[\t ]*"/g, "$1 - \"") // text-"text -> text - "text
         .replace(/([^\s-])[\t ]*-\([\t ]*/g, "$1 - (") // text-(text -> text - (text
         .replace(/([^\s-])[\t ]*\)-[\t ]*/g, "$1) - ") // text)-text -> text) - text
         .replace(/([^\s-])[\t ]*-[\t ]+/g, "$1 - ")    // text- text -> text - text
         .replace(/([^\s-])[\t ]+-[\t ]*/g, "$1 - ")    // text -text -> text - text
         .replace(/^([\t ]*)-{1,3}[\t ]*/mg, "$1- ") // \n-text -> \n- text
         .replace(/([^\s-])[\t ]*---?[\t ]*/g, "$1 - ")   // text--text -> text - text
         .replace(/ - /g, " " + this.dash + " ");

      // Fix commas:
      if(this.convCommas)
         txt = txt
            .replace(/^[\t ]*"[\t ]*/mg, this.openComma)  // \n" -> \n«
            .replace(/[\t ]*"[\t ]*$/mg, this.closeComma) // "\n -> »\n
            .replace(/([.?!])"(\s)/g, "$1" + this.closeComma + "$2") // 'text!" ' -> 'text!» '
            .replace(/([а-яёa-z])"([-+\s.?!,;:\)\}\]\>]|$)/img, "$1" + this.closeComma + "$2") // text". -> text».
            .replace(/[\t ]*"[\t ]*([-+.?!,;:\)\}\]\>]|$)/mg, this.closeComma + "$1")          // ' " .' -> '».'
            .replace(/(^|[\s\(\{\[<])"[\t ]*/mg, "$1" + this.openComma)
            .replace(new RegExp(this.openComma + "[\\t ]+", "g"), this.openComma)
            .replace(new RegExp("[\\t ]+" + this.closeComma, "g"), this.closeComma);

      // Fix dashes (end):
      txt = txt.replace(/- /g, this.dash + " ");

      // Replace exclusions:
      while(excCnt > -1) {
         txt = txt.replace(
            new RegExp(this.subst + excCnt + "_", "g"),
            function() { return _this.notConv[excCnt].shift(); }
         );
         excCnt--;
      }

      // Del spaces:
      txt = txt
         .replace(/(\S)([ \t])[ \t]+/g, "$1$2") // "\t  " -> "\t", " \t\t" -> " "
         .replace(/[ \t]+$/mg, ""); // "text  \n" -> "text\n"

      return txt;
   }
};

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit)) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(lpPoint) {
      setRedraw(hWndEdit, false);
      var selParams = getSelParams();
      AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

      // Get selection or all text and save fullTxt flag:
      var txt = AkelPad.GetSelText();
      var fullTxt = !txt;
      if(fullTxt)
         txt = AkelPad.SetSel(0, -1) || AkelPad.GetSelText();

      var selStart = AkelPad.GetSelStart();
      var err;
      try {
         var fixer = new PunctuationFixer(fixerDash, fixerForceUpperCase, fixerCommas);
         txt = fixer.convert(txt);
         AkelPad.ReplaceSel(txt);
         if(!fixerSaveSelPos || !fullTxt)
            selParams = [selStart, selStart + txt.length];
      }
      catch(e) {
         err = e;
      }

      restoreSelParams(selParams);
      AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
      setRedraw(hWndEdit, true);
      AkelPad.MemFree(lpPoint);

      if(err)
         throw err;
   }
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   if(bRedraw)
      oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getSelParams() {
   return [AkelPad.GetSelStart(), AkelPad.GetSelEnd()];
}
function restoreSelParams(selParams) {
   AkelPad.SetSel(selParams[0], selParams[1]);
}
<download>

colorsConverter.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/colorsConverter.js

// (c) Infocatcher 2010-2011
// version 0.1.2 - 2011-12-20

function _localize(s) {
   var strings = {
      "Color:": {
         ru: "Цвет:"
      },
      "Color from “%S”:": {
         ru: "Цвет из «%S»:"
      },
      "Invalid color format!": {
         ru: "Некорректный формат цвета!"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();

if(hMainWnd)
   convColor(AkelPad.GetSelText());

function convColor(color, forceAsk) {
   if(!color || forceAsk)
      color = askColor(_localize("Color:"), color);
   if(!color)
      return;
   var newColor;
   if(/^\W*#?([0-9a-f]{3}|[0-9a-f]{6})\W*$/i.test(color)) // #aaa or #aaaaaa
      newColor = h2d(RegExp.$1);
   else if(/^\D*(\d{1,3}\D+\d{1,3}\D+\d{1,3})\D*$/.test(color)) // rgb(170, 170, 170)
      newColor = d2h.apply(this, RegExp.$1.split(/\D+/));

   if(!newColor) {
      AkelPad.MessageBox(hMainWnd, _localize("Invalid color format!"), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
      convColor(color, true);
      return;
   }
   newColor = askColor(_localize("Color from “%S”:").replace("%S", color), newColor);
   newColor && convColor(newColor);
}
function askColor(caption, defaultValue) {
   return AkelPad.InputBox(
      hMainWnd, WScript.ScriptName,
      caption,
      defaultValue || ""
   );
}

function hex(n) {
   var h = (typeof n == "number" ? n : parseInt(n, 10)).toString(16);
   if(h.length > 2)
      return null;
   return "00".substr(h.length) + h;
}
function d2h() {
   var i, h, r = [], l = arguments.length;
   var same = /^([0-9a-f])\1$/i;
   var isSame = true;
   for(i = 0; i < l; i++) {
      h = hex(arguments[i]);
      if(!h)
         return null;
      if(isSame && !same.test(h))
         isSame = false;
      r.push(h);
   }
   if(isSame)
      for(i = 0; i < l; i++)
         r[i] = r[i].charAt(0);
   return /* "#" + */ r.join("");
}
function h2d(h) {
   var l = h.length;
   var s = l == 3 ? 1 : 2;
   var i, r = [], h2;
   for(var i = 0; i < l; i += s) {
      h2 = h.substr(i, s);
      if(s == 1)
         h2 += h2;
      r.push(parseInt(h2, 16));
   }
   return r.join(", ");
}
<download>
Convert color between «#fee» and «rgb(255, 238, 238)» formats.

copyPath.js
Code:
// (c) Infocatcher 2010
// version 0.1.0 - 2010-06-22

// Usage:
//   -"Copy path to file"                Call("Scripts::Main", 1, "copyPath.js", `"%f"`)
// Or with template:
//   -"Copy path to file"                Call("Scripts::Main", 1, "copyPath.js", `"%f" "<path>/<file>.<ext>"`)
//   -"Copy path to file directory"      Call("Scripts::Main", 1, "copyPath.js", `"%f" "<path>"`)
//   -"Copy file name"                   Call("Scripts::Main", 1, "copyPath.js", `"%f" "<file>.<ext>"`)
//   -"Copy file name without extension" Call("Scripts::Main", 1, "copyPath.js", `"%f" "<file>"`)

var argsCount = WScript.Arguments.length;
if(argsCount) {
   var arg = WScript.Arguments(0);
   if(argsCount > 1) {
      var path = arg, sep = "", file = "", dot ="", ext = "";
      if(/([\\/])?([^\\/]*)$/.test(path)) {
         sep = RegExp.$1;
         file = RegExp.$2;
         path = path.substring(0, path.length - RegExp.lastMatch.length);
         if(/\.([^.]+)$/.test(file)) {
            dot = ".";
            ext = RegExp.$1;
            file = file.substring(0, file.length - RegExp.lastMatch.length);
         }
      }
      arg = WScript.Arguments(1)
         .replace("<path>", path)
         .replace("/", sep)
         .replace("<file>", file)
         .replace(".", dot)
         .replace("<ext>", ext);
   }
   //var AkelPad = new ActiveXObject("AkelPad.document");
   AkelPad.SetClipboardText(arg);
}
<download>
Copy path to file in configurable format.

getLinks.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/getLinks.js

// (c) Infocatcher 2009-2011
// version 0.1.7 - 2011-12-20

//===================
// Tries to extract links from any text

// Usage:
//   Call("Scripts::Main", 1, "getLinks.js")
//===================

function _localize(s) {
   var strings = {
      "Links not found!": {
         ru: "Ссылки не найдены!"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd) {
   var links = getLinks();
   if(links.length) {
      AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
      AkelPad.SetSel(0, 0);
      insertNoScroll(links.join("\n"), true);
   }
   else {
      AkelPad.MessageBox(
         hMainWnd,
         _localize("Links not found!"),
         WScript.ScriptName,
         48 /*MB_ICONEXCLAMATION*/
      );
   }
}

function getLinks() {
   // Get selection or all text
   var txt = AkelPad.GetSelText() || getAllText();

   // [url=http://example.com/]...[/url] => http://example.com/
   txt = txt.replace(/\[(\w+)=(['"]?)([^\[\]]+)\2\].*?\[\/\1\]/g, "\t$3\t");

   var links = txt.match(/[a-z]+:\/\/+([^\/\\.\s<>'":*?|&#\(\)\[\]\{\}]+\.)*[^\/\\.\s<>'":*?|&#\(\)\[\]\{\}]+(:\d+)?(\/[^\s"<>]*)?|mailto:[^@\s\\\/:*?"<>|]+@[^@.\s\\\/:*?"<>|&#]+(\.[^@.\s\\\/:*?"<>|&#]+)+|\\{2,}\w+(\\[^\\\/:*?"<>|\s]+)+\\?/ig);
   if(!links)
      return [];

   var linksObj = {};
   var link;
   for(var i = 0, len = links.length; i < len; i++) {
      link = links[i].replace(/[\(\{\[+,]$/, "");

      if(count(link, /\(/g) == 0 && count(link, /\)/g))
         link = link.replace(/\).*$/, "");
      if(count(link, /\[/g) == 0 && count(link, /\]/g))
         link = link.replace(/\].*$/, "");
      if(count(link, /\{/g) == 0 && count(link, /\}/g))
         link = link.replace(/\}.*$/, "");

      linksObj[decodeHTML(link)] = 1;
   }

   links = [];
   for(var h in linksObj)
      links.push(h);

   return links;
}
function count(s, re) {
   var m = s.match(re);
   return m ? m.length : 0;
}
function decodeHTML(s) {
   return s
      .replace(/&amp;/g, "&")
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">")
      .replace(/&quot;/g, '"');
}

function getAllText() {
   if(typeof AkelPad.GetTextRange != "undefined")
      return AkelPad.GetTextRange(0, -1);
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return "";
   var hWndEdit = AkelPad.GetEditWnd();
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
   var ss = AkelPad.GetSelStart();
   var se = AkelPad.GetSelEnd();

   AkelPad.SetSel(0, -1);
   var str = AkelPad.GetSelText();

   AkelPad.SetSel(ss, se);
   columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   AkelPad.MemFree(lpPoint);
   setRedraw(hWndEdit, true);
   return str;
}
function insertNoScroll(str, selectAll) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return;
   var hWndEdit = AkelPad.GetEditWnd();
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   selectAll && AkelPad.SetSel(0, -1);
   //var ss = AkelPad.GetSelStart();
   AkelPad.ReplaceSel(str, true);
   //if(ss != AkelPad.GetSelStart())
   //   AkelPad.SetSel(ss, ss + str.length);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   setRedraw(hWndEdit, true);
   AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Tries to extract links from any text.

insertEval.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/insertEval.js

// (c) Infocatcher 2010-2011
// version 0.1.9 - 2011-12-20

//===================
// Special expressions:
// =someExpression() => "someExpression() = result"

// Usage:
//   Call("Scripts::Main", 1, "insertEval.js")
//===================

function _localize(s) {
   var strings = {
      "Expression:": {
         ru: "Выражение:"
      },
      "Result:": {
         ru: "Результат:"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

var document = new ActiveXObject("htmlfile");
// Initialize document (we can't use something like document.documentElement without this):
document.open();
document.close();
var window = document.parentWindow;

var utils = {
   alert: function(msg, icon, addTitle) {
      AkelPad.MessageBox(hMainWnd, String(msg), dialogTitle + (addTitle ? " :: " + addTitle : ""), icon || 48 /*MB_ICONEXCLAMATION*/);
   },
   prompt: function(msg, defaultVel) {
      var ret = AkelPad.InputBox(hMainWnd, dialogTitle, String(msg), defaultVel);
      return ret == undefined ? null : ret;
   },
   confirm: function(msg) {
      return AkelPad.MessageBox(hMainWnd, String(msg), dialogTitle, 33 /*MB_OKCANCEL|MB_ICONQUESTION*/) == 1 /*IDOK*/;
   },
   setTimeout: function(func, delay) {
      return window.setTimeout(func, delay);
   },
   setInterval: function(func, delay) {
      return window.setInterval(func, delay);
   },
   document: {
      open: function() {},
      write: function(s) {
         utils.alert(s, null, "document.write");
      },
      writeln: function(s) {
         utils.alert(s, null, "document.writeln");
      },
      close: function() {}
   },
   print: function(s) {
      utils.alert(s, null, "print");
   },

   hex: function(n) {
      n = Number(n);
      return (n < 0 ? "-" : "") + "0x" + Math.abs(n).toString(16);
   },
   oct: function(n) {
      return "0" + Number(n).toString(8);
   },
   bin: function(n) {
      return "b" + Number(n).toString(2);
   },
   p: function(n) {
      return String(n).replace(/(\d)(?=(?:\d{3})+(?:\D|$))/g, "$1 ");
   },

   append: function(s) {
      var sep = "\n";
      s = String(s);

      var hWndEdit = AkelPad.GetEditWnd();
      setRedraw(hWndEdit, false);

      var se = AkelPad.GetSelEnd();
      AkelPad.SetSel(se, se);
      AkelPad.ReplaceSel(sep + s);
      se += sep.length;
      AkelPad.SetSel(se, se + s.length);

      setRedraw(hWndEdit, true);
   },

   _logMsgs: [],
   _log: function() {
      for(var i = 0, l = arguments.length; i < l; i++)
         this._logMsgs.push(arguments[i]);
   }
};
utils.window = utils;

function calc(expr, forceAsk) {
   if(!expr || forceAsk)
      expr = utils.prompt(_localize("Expression:"), expr);
   if(!expr)
      return;
   if(/^\s*=\s*/.test(expr)) {
      expr = expr.substr(RegExp.lastMatch.length);
      var extOutput = true;
   }
   var isHex = /^0x[\da-f]/i.test(expr);
   var res;
   try {
      with(Math) with(WScript) with(utils) with(AkelPad)
         res = eval(expr);
   }
   catch(e) {
      utils.alert(e.name + "\n" + e.message, 16 /*MB_ICONERROR*/);
      calc(expr, true);
      return;
   }
   if(isHex && typeof res == "number")
      res = utils.hex(res);
   else
      res = String(res);
   var newExpr = utils.prompt(_localize("Result:"), res);
   if(!newExpr)
      return; // Cancel
   if(newExpr != res) {
      calc(newExpr);
      return;
   }
   if(extOutput)
      res = expr + " = " + res;
   if(res == AkelPad.GetSelText())
      return;
   if(!AkelPad.GetEditReadOnly(AkelPad.GetEditWnd()))
      AkelPad.ReplaceSel(res);
}

if(hMainWnd) {
   calc(AkelPad.GetSelText());
   if(utils._logMsgs.length) {
      AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
      AkelPad.SetSel(0, 0);
      insertNoScroll(utils._logMsgs.join("\n"), true);
   }
}

function insertNoScroll(str, selectAll) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return;
   var hWndEdit = AkelPad.GetEditWnd();
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   selectAll && AkelPad.SetSel(0, -1);
   AkelPad.ReplaceSel(str);
   AkelPad.SetSel(0, 0);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   setRedraw(hWndEdit, true);
   AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Script like built-in Calculator.js.

newFileTemplate.js
Code:
// (c) Infocatcher 2009
// version 0.2.5 - 2010-06-21

// Usage:
// Call("Scripts::Main", 1, "newFileTemplate.js", "html", 0)
//   - use template for "html"
// Call("Scripts::Main", 1, "newFileTemplate.js", "", 0)
//   - use template for extension of current file
// Call("Scripts::Main", 1, "newFileTemplate.js", "?", 0)
//   - ask user about extension
// Call("Scripts::Main", 1, "newFileTemplate.js", `"%f"`, 0)
//   - use active file (e.g. in ContextMenu plugin)
//   - or `"c:\\path\to\my\file\myFile.ext"` instead of `"%f"`

// Settings begin
var templatesDir = "%a\\AkelFiles\\Plugs\\Scripts\\Params\\" + getScriptDirName();
// For "script.js" getScriptDirName() return "script".
var templateFileName = "template";
var selFlag = "%|";
var selTextFlag = "%s";
// Settings end

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

var locale = {
   lng: null,
   strings: {
      extRequired: {
         ru: "Расширение нового файла: ",
         en: "Extension of new file: "
      }
   },
   getStr: function(name) {
      if(!this.lng) {
         var nLangID = oSys.Call("kernel32::GetUserDefaultLangID");
         nLangID = nLangID & 0x3ff; //PRIMARYLANGID
         switch(nLangID) {
            case 0x19: this.lng = "ru"; break;
            default:   this.lng = "en";
         }
      }
      return this.strings[name][this.lng];
   }
};

function TemplateMaker(tDir, tFileName, selFlag, selTextFlag) {
   this.tDir = tDir;
   this.tFileName = tFileName;
   this.selFlag = selFlag;
   this.selTextFlag = selTextFlag;
}
TemplateMaker.prototype = {
   initTemplate: function() {
      this.ext = this.getExt();
      return this.getTemplate();
   },
   getExt: function() {
      var ext;
      if(WScript.Arguments.length) {
         ext = WScript.Arguments(0);
         if(ext == "?")
            return this.ackUserExt();
         else if(ext && /\\.*\.([^.]+)$/.test(ext)) { // ...\filename.ext
            this.tPath = ext;
            ext = RegExp.$1;
            this.precessTemplate = false;
         }
      }
      ext = ext || this.getCurrentExt() || this.ackUserExt();
      return ext && ext.toLowerCase();
   },
   ackUserExt: function() {
      var ext = AkelPad.InputBox(
         hMainWnd, WScript.ScriptName,
         locale.getStr("extRequired"),
         this.getCurrentExt() || regVal("lastExt") || ""
      );
      return ext && ext.toLowerCase();
   },
   getCurrentExt: function() {
      if(!this._getCurrentExt) {
         var cFile = AkelPad.GetEditFile(0);
         this._getCurrentExt = cFile && /\.([^.]+)$/i.test(cFile) && RegExp.$1;
      }
      return this._getCurrentExt;
   },
   tPath: null,
   tmpl: "",
   precessTemplate: true,
   selParams: null,
   getTemplate: function() {
      if(!this.ext)
         return false;
      var pFile = this.tPath
         || this.tDir
            .replace("%a", AkelPad.GetAkelDir())
            .replace(/\\?$/, "\\")
            + this.tFileName + "." + this.ext;
      if(!this.fileExist(pFile))
         return true;
      this.tmpl = AkelPad.ReadFile(pFile)
         .replace(/\r\n/g, "\n"); // For AkelPad 4.4.4
      if(!this.precessTemplate)
         return true;
      if(this.tmpl.indexOf(this.selTextFlag) != -1)
         this.tmpl = this.tmpl.replace(this.selTextFlag, AkelPad.GetSelText());
      var selStart = this.tmpl.indexOf(this.selFlag);
      this.delFlag(selStart);
      var selEnd = this.tmpl.lastIndexOf(this.selFlag);
      this.delFlag(selEnd);
      if(selStart != -1 && selEnd == -1)
         selEnd = selStart;
      this.selParams = selStart != -1
         ? [selStart, selEnd]
         : null;
      return true;
   },
   fileExist: function(fName) {
      return new ActiveXObject("Scripting.FileSystemObject")
         .FileExists(fName);
   },
   delFlag: function(pos) {
      if(pos != -1)
         this.tmpl = this.tmpl.substring(0, pos)
            + this.tmpl.substring(pos + this.selFlag.length, this.tmpl.length);
   },
   insTemplate: function() {
      AkelPad.ReplaceSel(this.tmpl);
      this.formatTemplate();
      regVal("lastExt", this.ext);
   },
   formatTemplate: function() {
      var ext = this.ext;
      if(ext) {
         //AkelPad.Call("HighLight::Main", 1, ext);
         //AkelPad.Call("AutoComplete::Main", 1, ext);
         AkelPad.Call("Coder::Settings", 1, ext);
      }
      var sp = this.selParams;
      if(sp)
         AkelPad.SetSel(sp[0], sp[1]);
      else
         AkelPad.SetSel(0, 0);
   }
};

if(hMainWnd) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(lpPoint) {
      var tm = new TemplateMaker(templatesDir, templateFileName, selFlag, selTextFlag);
      if(tm.initTemplate()) {
         AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
         var hWndEditNew = AkelPad.GetEditWnd();
         setRedraw(hWndEditNew, false);
         AkelPad.SendMessage(hWndEditNew, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

         tm.insTemplate();

         AkelPad.SendMessage(hWndEditNew, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
         setRedraw(hWndEditNew, true);
         AkelPad.MemFree(lpPoint);
      }
   }
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   if(bRedraw)
      oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getScriptDirName() {
   return WScript.ScriptName.replace(/\.js$/i, "");
}
function regVal(name, val) {
   name = "HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\newFileTemplate\\" + name;
   var ws = new ActiveXObject("WScript.shell");
   if(typeof val != "undefined")
      return ws.RegWrite(name, val, "REG_SZ");
   try { return ws.RegRead(name); }
   catch(e) { return ""; }
}
<download>
newFileTemplate-test.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#9926

// (c) Infocatcher 2009-2011
// version 0.3.2 - 2011-12-20

// Works with ShowMenuEx.js http://akelpad.sourceforge.net/forum/viewtopic.php?p=8153#8153

// Usage:
// Call("Scripts::Main", 1, "newFileTemplate.js", "html")
//   - use template for "html"
// Call("Scripts::Main", 1, "newFileTemplate.js")
//   - use template for extension of current file
// Call("Scripts::Main", 1, "newFileTemplate.js", "?")
//   - ask user about extension
// Call("Scripts::Main", 1, "newFileTemplate.js", `"%f"`)
//   - use active file (e.g. in ContextMenu plugin)
//   - or `"c:\\path\to\my\file\myFile.ext"` instead of `"%f"`
// Call("Scripts::Main", 1, "newFileTemplate.js", "?edit")
//   - edit template
// Call("Scripts::Main", 1, "newFileTemplate.js", "?edit:html")
//   - edit template for "html"

//== Settings begin
var templatesDir = "%a\\AkelFiles\\Plugs\\Scripts\\Params\\" + getScriptDirName();
// For "script.js" getScriptDirName() return "script".
var templateFileName = "template";
var selFlag = "%|";
var selTextFlag = "%s";
//== Settings end

function _localize(s) {
   var strings = {
      "Extension of new file:": {
         ru: "Расширение нового файла:"
      },
      "Edit template for extension:": {
         ru: "Редактировать шаблон для расширения:"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

var argAsk = "?";
var argEdit = "?edit";

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var wsh = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

function TemplateMaker(tDir, tFileName, selFlag, selTextFlag, argAsk, argEdit) {
   this.tDir = tDir;
   this.tFileName = tFileName;
   this.selFlag = selFlag;
   this.selTextFlag = selTextFlag;
   this.argAsk = argAsk;
   this.argEdit = argEdit;
}
TemplateMaker.prototype = {
   initTemplate: function() {
      this.ext = this.getExt();
      return this.getTemplate();
   },
   getExt: function() {
      var ext;
      if(WScript.Arguments.length) {
         ext = this.parseSpecialExts(WScript.Arguments(0));
         return ext && ext.toLowerCase();
      }
      ext = ext || this.getCurrentExt() || this.askUserExt();
      return ext && ext.toLowerCase();
   },
   parseSpecialExts: function(ext, retExt) {
      if(ext == this.argAsk)
         return this.askUserExtInput();
      else if(ext && ext.indexOf(this.argEdit) == 0) {
         this.createTemplate(ext.substr(this.argEdit.length + 1));
         return "";
      }
      else if(ext && /\\.*\.([^.]+)$/.test(ext)) { // ...\filename.ext
         this.tPath = ext;
         ext = RegExp.$1;
         this.precessTemplate = false;
         return ext && ext.toLowerCase();
      }
      return retExt ? ext : "";
   },
   askUserExt: function() {
      if(this.asked)
         return "";
      var ext;
      var showMenuPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Plugs\\Scripts\\ShowMenuEx.js";
      if(fso.FileExists(showMenuPath)) {
         eval(AkelPad.ReadFile(showMenuPath));
         ext = getSelectedMenuItem(POS_CURSOR, "INI", 0);
         ext = this.parseSpecialExts(ext, true);
      }
      else {
         ext = this.askUserExtInput();
      }
      return ext && ext.toLowerCase();
   },
   asked: false,
   askUserExtInput: function(newFlag) {
      this.asked = true;
      var ext = AkelPad.InputBox(
         hMainWnd, WScript.ScriptName,
         _localize(
            newFlag
               ? "Edit template for extension:"
               : "Extension of new file:"
         ),
         this.getCurrentExt() || regVal("lastExt") || ""
      );
      return ext && ext.toLowerCase();
   },
   getCurrentExt: function() {
      if(!this._getCurrentExt) {
         var cFile = AkelPad.GetEditFile(0);
         this._getCurrentExt = cFile && /\.([^.]+)$/i.test(cFile) && RegExp.$1;
      }
      return this._getCurrentExt;
   },
   createTemplate: function(ext) {
      ext = ext || this.askUserExtInput(true /* newFlag */);
      if(!ext)
         return;
      var path = this.getTemplatePath(ext);

      var dir = fso.GetParentFolderName(path);
      if(!fso.FolderExists(dir))
         fso.CreateFolder(dir);

      AkelPad.OpenFile(path);
   },
   tPath: "",
   tmpl: "",
   precessTemplate: true,
   selParams: null,
   getTemplate: function() {
      if(!this.ext)
         return false;
      var pFile = this.tPath || this.getTemplatePath(this.ext);
      if(!fso.FileExists(pFile))
         return true;
      this.tmpl = AkelPad.ReadFile(pFile)
         .replace(/\r\n/g, "\n"); // For AkelPad 4.4.4+
      if(!this.precessTemplate)
         return true;
      if(this.tmpl.indexOf(this.selTextFlag) != -1)
         this.tmpl = this.tmpl.replace(this.selTextFlag, AkelPad.GetSelText());
      var selStart = this.tmpl.indexOf(this.selFlag);
      this.delFlag(selStart);
      var selEnd = this.tmpl.lastIndexOf(this.selFlag);
      this.delFlag(selEnd);
      if(selStart != -1 && selEnd == -1)
         selEnd = selStart;
      this.selParams = selStart != -1
         ? [selStart, selEnd]
         : null;
      return true;
   },
   getTemplatePath: function(ext) {
      return wsh.ExpandEnvironmentStrings(
         this.tDir
            .replace(/^%a/, AkelPad.GetAkelDir())
            .replace(/\\$/, "")
            + "\\" + this.tFileName + "." + ext
      );
   },
   delFlag: function(pos) {
      if(pos != -1)
         this.tmpl = this.tmpl.substring(0, pos)
            + this.tmpl.substring(pos + this.selFlag.length, this.tmpl.length);
   },
   insTemplate: function() {
      AkelPad.ReplaceSel(this.tmpl);
      this.formatTemplate();
      regVal("lastExt", this.ext);
   },
   formatTemplate: function() {
      var ext = this.ext;
      if (ext && AkelPad.IsPluginRunning("Coder::HighLight") == true) {
         AkelPad.Call("Coder::Settings", 1, ext);
      }
      var sp = this.selParams;
      if(sp)
         AkelPad.SetSel(sp[0], sp[1]);
      else
         AkelPad.SetSel(0, 0);
   }
};

if(hMainWnd) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(lpPoint) {
      var tm = new TemplateMaker(templatesDir, templateFileName, selFlag, selTextFlag, argAsk, argEdit);
      if(tm.initTemplate()) {
         AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
         var hWndEditNew = AkelPad.GetEditWnd();
         setRedraw(hWndEditNew, false);
         AkelPad.SendMessage(hWndEditNew, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

         tm.insTemplate();

         AkelPad.SendMessage(hWndEditNew, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
         setRedraw(hWndEditNew, true);
         AkelPad.MemFree(lpPoint);
      }
   }
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getScriptDirName() {
   return WScript.ScriptName.replace(/\.js$/i, "");
}
function regVal(name, val) {
   name = "HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\newFileTemplate\\" + name;
   if(arguments.length == 2)
      return wsh.RegWrite(name, val, "REG_SZ");
   try { return wsh.RegRead(name); }
   catch(e) { return ""; }
}
<download>
Create new file from template.


Last edited by Infocatcher on Fri May 11, 2012 6:18 pm; edited 11 times in total
Back to top
View user's profile Send private message
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Sat Nov 13, 2010 6:41 pm    Post subject: Reply with quote

openFileIn.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/openFileIn.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/openFileIn.js

// (c) Infocatcher 2010-2013
// version 0.2.0 - 2013-02-25

//===================
// Open file in other application

// Usage:
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%f"')
// In "URL menu":
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%u"')
// Disable mappings:
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%f" -mappings=false')
//===================

//== Settings begin
// You can use openFileIn-options.js file for override or tweak settings
// Override:
//   var appsData = { ... };
// Tweak:
//   appsData["App"] = { ... };       - add application
//   appsData["App"].paths = [ ... ]  - change paths
var mappings = {
   // Only for applications marked as 'isBrowser: true'
   // Example:
   // "D:\\Site\\": "http://localhost/",
   // "D:\\AnotherSite\\": "http://example.com/"
};
var appsData = {
   // Example:
   //   "appID": {
   //      paths: [
   //         "c:\\path\\to\\app.exe",
   //         "%EnvVar%\\another\\path\\to\\app.exe",
   //         "<HKCU\\path\\from\\registry>app.exe",
   //         "?x64?...\\app64.exe", // Check only on x64 system
   //         "?x86?...\\app32.exe"  // Check only on x86 system
   //      ],
   //      args: "-file:%f -line:%l",
   //      isBrowser: true
   //   }
   "Total Commander": {
      paths: [
         "%COMMANDER_EXE%",
         "%COMMANDER_PATH%\\TOTALCMD.EXE",
         "?x64?%COMMANDER_PATH%\\TOTALCMD64.EXE",
         "%AkelDir%\\..\\totalcmd\\TOTALCMD.EXE",
         "%AkelDir%\\..\\Total Commander\\TOTALCMD.EXE",
         "%__portable__%\\totalcmd\\TOTALCMD.EXE",
         "?x64?<HKCU\\Software\\Ghisler\\Total Commander\\InstallDir>\\TOTALCMD64.EXE",
         "<HKCU\\Software\\Ghisler\\Total Commander\\InstallDir>\\TOTALCMD.EXE",
         "%ProgramFiles%\\totalcmd\\TOTALCMD.EXE",
         "%ProgramFiles%\\Total Commander\\TOTALCMD.EXE"
      ],
      args: "/O /S /T %f"
   },

   "Notepad": {
      paths: [
         "%SystemRoot%\\notepad.exe"
      ],
      args: "%f"
   },
   "Notepad++": {
      paths: [
         "%COMMANDER_PATH%\\..\\Notepad++\\notepad++.exe",
         "%AkelDir%\\..\\Notepad++\\notepad++.exe",
         "%__portable__%\\Notepad++\\notepad++.exe",
         "%ProgramFiles%\\Notepad++\\notepad++.exe"
      ],
      args: "%f -n%l"
   },
   "PSPad": {
      paths: [
         "%COMMANDER_PATH%\\..\\PSPad\\PSPad.exe",
         "%COMMANDER_PATH%\\..\\PSPad editor\\PSPad.exe",
         "%AkelDir%\\..\\PSPad\\PSPad.exe",
         "%AkelDir%\\..\\PSPad editor\\PSPad.exe",
         "%ProgramFiles%\\PSPad\\PSPad.exe",
         "%ProgramFiles%\\PSPad editor\\PSPad.exe"
      ],
      args: "%f"
   },
   "EmEditor": {
      paths: [
         "%COMMANDER_PATH%\\..\\EmEditor\\EmEditor.exe",
         "%AkelDir%\\..\\EmEditor\\EmEditor.exe",
         "%ProgramFiles%\\EmEditor\\EmEditor.exe"
      ],
      args: "%f"
   },

   "Internet Explorer": {
      paths: [
         "%ProgramFiles%\\Internet Explorer\\iexplore.exe"
      ],
      args: "%f",
      isBrowser: true
   },
   "Firefox": {
      paths: [
         "<HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe\\>",
         "%ProgramFiles%\\Mozilla Firefox\\firefox.exe",
         "%COMMANDER_PATH%\\..\\FirefoxPortable\\FirefoxPortable.exe",
         "%AkelDir%\\..\\FirefoxPortable\\FirefoxPortable.exe"
      ],
      args: "%f",
      isBrowser: true
   },
   "Opera": {
      paths: [
         "<HKCU\\Software\\Opera Software\\Last Install Path>\\opera.exe",
         "%ProgramFiles%\\Opera\\opera.exe",
         "%COMMANDER_PATH%\\..\\OperaUSB\\opera.exe",
         "%COMMANDER_PATH%\\..\\Opera\\opera.exe",
         "%AkelDir%\\..\\OperaUSB\\opera.exe",
         "%AkelDir%\\..\\Opera\\opera.exe"
      ],
      args: "%f",
      isBrowser: true
   },
   "Google Chrome": {
      paths: [
         "<HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\\>",
         "<HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\\>",
         "%LocalAppData%\\Google\\Chrome\\Application\\chrome.exe",
         "%UserProfile%\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
         "%UserProfile%\\Local Settings\\Application Data\\Bromium\\Application\\chrome.exe",
         "%COMMANDER_PATH%\\..\\GoogleChromePortable\\GoogleChromePortable.exe",
         "%AkelDir%\\..\\GoogleChromePortable\\GoogleChromePortable.exe"
      ],
      args: "%f",
      isBrowser: true
   },
   "Safari": {
      paths: [
         "%ProgramFiles%\\Safari\\Safari.exe",
         "%COMMANDER_PATH%\\..\\SafariPortable\\SafariPortable.exe",
         "%AkelDir%\\..\\SafariPortable\\SafariPortable.exe"
      ],
      args: "%f",
      isBrowser: true
   }
};
//== Settings end

var optionsPath = WScript.ScriptFullName.replace(/(\.[^.]+)?$/, "-options$&");
var fso = new ActiveXObject("Scripting.FileSystemObject");
if(fso.FileExists(optionsPath))
   eval(AkelPad.ReadFile(optionsPath));

var allowMappings = AkelPad.GetArgValue("mappings", true);

var wsh = new ActiveXObject("WScript.Shell");
var akelDir = AkelPad.GetAkelDir();

if(WScript.Arguments.length >= 2) {
   var app = WScript.Arguments(0);
   var file = WScript.Arguments(1);
   if(app in appsData) {
      var appData = appsData[app];
      var path = getPath(appData.paths);
      if(path) {
         if(appData.isBrowser) {
            for(var p in mappings) {
               var pl = p.length;
               if(file.substr(0, pl) == p) {
                  file = mappings[p] + file.substr(pl).replace(/\\/g, "/");
                  break;
               }
            }
         }
         var args = appData.args;
         if(file) {
            if(/%f/.test(args))
               args = args.replace(/%f/g, '"' + file + '"');
            if(/%l/.test(args))
               args = args.replace(/%l/g, getLine());
         }
         else {
            args = args
               .replace(/\s*\S*%f\S*\s*/g, " ")
               .replace(/\s*\S*%l\S*\s*/g, " ");
         }
         var cmdLine = ('"' + path + '" ' + args).replace(/\s+$/, "");
         try {
            wsh.Exec(cmdLine);
         }
         catch(e) {
            // Windows Vista/7 and admin rights required
            //WScript.Echo(e.name + "\n" + e.message);
            new ActiveXObject("Shell.Application").ShellExecute(path, args, "" /*directory*/, "runas");
         }
      }
      else {
         warn(app + " not found!\n\n" + appData.paths.join("\n"));
      }
   }
   else {
      warn("Application with id \"" + app + "\" not found in database!");
   }
}
else {
   warn('Wrong arguments!\nUsage:\nCall("Scripts::Main", 1, "' + WScript.ScriptName + '", \'"appID" "%f"\')');
}
function getPath(paths) {
   for(var i = 0, l = paths.length; i < l; ++i) {
      var path = paths[i];
      if(path.charAt(0) == "?") {
         if(path.substr(0, 5) != (_X64 ? "?x64?" : "?x86?"))
            continue;
         path = path.substr(5);
      }
      var path = expandVariables(paths[i]);
      //WScript.Echo(paths[i] + "\n=>\n" + path);
      if(fso.FileExists(path))
         return path;
   }
   return "";
}
function expandVariables(s) {
   return expandEnvironmentVariables(expandRegistryVariables(s));
}
function expandEnvironmentVariables(s) {
   return wsh.ExpandEnvironmentStrings(s.replace(/^%AkelDir%/, akelDir));
}
function expandRegistryVariables(s) { // <HKCU\Software\Foo\installPath>\foo.exe
   return s.replace(/<(.+?)>/g, function(s, path) {
      var val = getRegistryValue(path);
      if(val)
         return val;
      return s;
   });
}
function getRegistryValue(path) {
   try {
      return wsh.RegRead(path);
   }
   catch(e) {
   }
   return "";
}
function getLine() {
   var hWndEdit = AkelPad.GetEditWnd();
   var wrpLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, AkelPad.GetSelStart());
   var unwrpLine = AkelPad.SendMessage(hWndEdit, 3143 /*AEM_GETUNWRAPLINE*/, wrpLine, 0);
   return unwrpLine + 1;
}
function warn(msg) {
   AkelPad.MessageBox(AkelPad.GetMainWnd(), msg, WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
}
<download | mirror | development version>
Example for open file in other application.

scriptToBookmarklet.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/scriptToBookmarklet.js

// (c) Infocatcher 2008-2011
// version 0.3.0 - 2011-12-20
// Windows XP +

//===================
// Convert JavaScript code to one line bookmarklet
// http://en.wikipedia.org/wiki/Bookmarklet
// http://ru.wikipedia.org/wiki/Букмарклет

// Arguments:
//   -saveSpaces=0         - replace multiple spaces with one
//              =1         - don't replace spaces inside lines
//              =2         - only replace new lines
//   -removeNewLines=true  - remove new lines instead of replace them with space
//   -saveComments=0       - sum of flags: 1 - save block comments, 2 - save line comments

// Usage:
//   Call("Scripts::Main", 1, "converter.js")
//   Call("Scripts::Main", 1, "converter.js", "-saveSpaces=0 -removeNewLines=true -saveComments=3")
//===================

function _localize(s) {
   var strings = {
      "Code of bookmarklet (OK - copy):": {
         ru: "Код букмарклета (ОК - копировать):"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

var saveSpaces     = getArg("saveSpaces", 0);
var removeNewLines = getArg("removeNewLines", true);
var saveComments   = getArg("saveComments", 0);

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
   scriptToBookmarklet();

function scriptToBookmarklet() {
   var text = getText();

   var excludes = {};
   var rnd = function() {
      return "<#" + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2) + "#>";
   };

   text = text
      // Remove "strings" and 'strings'
      .replace(
         /"(\\.|[^"\\\n\r])*"|'(\\.|[^'\\\n\r])*'/g,
         function(s) {
            var r = rnd();
            excludes[r] = s;
            return r;
         }
      )
      // Try remove regular expressions like /x*/ and /\/*x/
      // We search for invalid divisions:
      // x = /./;            -> =
      // if(/a/.test(b))     -> (
      // a = [/a/, /b/]      -> [ ,
      // x = a && /b/test(c) -> & |
      // x = a ? /b/ : /c/   -> ? :
      // x = !/a/.test(b)    -> !
      .replace(
         /([=(\[,&|?:!]\s*((\/\/[^\n\r]*[\n\r]+|\/\*[\s\S]*?\*\/)\s*)*)\/([^*+?\\\/\n\r]|\\[^\n\r])(\\\/|[^\/\n\r])*\//g,
         // special chars   line comments       block comments         regexp begin                         regexp end
         function(s, prefix) {
            var r = rnd();
            excludes[r] = s.substr(prefix.length);
            return prefix + r;
         }
      );


   if(!(saveComments & 1))
      text = text.replace(/\/\*[\s\S]*?\*\//g, ""); // /*comment*/
   if(!(saveComments & 2))
      text = text.replace(/(^|[\t ]+|([^:\\]))\/\/[^\n\r]*$/mg, "$2"); // //comment
   else
      text = text
         .replace(/(^|[\t ]+|[^:\\])\/\/([ \t]?)[ \t]*([^\n\r]*)$/mg, "$1/*$2$3*/") // //comment -> /*comment*/
         .replace(/\*\/[\n\r]+\/\*/g, " ");

   text = text
      .replace(/^\s*javascript:\s*/i, "")
      .replace(/^\s+|\s+$/g, "");

   var newLinesReplacement = removeNewLines ? "" : " ";

   if(saveSpaces == 0)
      text = text.replace(/\s+/g, " ");
   else if(saveSpaces == 1)
      text = text
         .replace(/^[ \t]+|[ \t]+$/mg, "")
         .replace(/[\n\r]+/g, newLinesReplacement);
   else if(saveSpaces >= 2)
      text = text.replace(/[\n\r]+/g, newLinesReplacement);


   text = text.replace(/<#[a-z0-9]{2,}#>/g, function(s) {
      if(s in excludes)
         return excludes[s];
      return s;
   });

   if(
      !/^\(function\s*\(\)\s*\{.+\}\)\s*\(\);?$/.test(text) // (function(){ ... })();
      && !/^alert\s*\(([^()]*\([^()]+\))*[^()]*\);?$/.test(text) // alert( ... );
      && !/\Walert\s*\(\s*[^)]+\s*\);?$/.test(text) // ... alert(x);
   )
      text += " void(0);";

   text = "javascript: " + text;

   text = AkelPad.InputBox(
      hMainWnd,
      WScript.ScriptName,
      _localize("Code of bookmarklet (OK - copy):"),
      text
   );
   if(text)
      AkelPad.SetClipboardText(text);
}
function getText() {
   // Get selection or all text
   var text = AkelPad.GetSelText();
   if(text)
      return text;
   if(typeof AkelPad.GetTextRange != "undefined")
      return AkelPad.GetTextRange(0, -1);
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(lpPoint) {
      setRedraw(hWndEdit, false);
      AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

      var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
      var ss = AkelPad.GetSelStart();
      var se = AkelPad.GetSelEnd();

      AkelPad.SetSel(0, -1);
      text = AkelPad.GetSelText();

      AkelPad.SetSel(ss, se);
      columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

      AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
      AkelPad.MemFree(lpPoint);
      setRedraw(hWndEdit, true);
   }
   return text;
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getArg(argName, defaultVal) {
   var args = {};
   for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
      if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
         args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
   getArg = function(argName, defaultVal) {
      argName = argName.toLowerCase();
      return typeof args[argName] == "undefined" // argName in args
         ? defaultVal
         : args[argName];
   };
   return getArg(argName, defaultVal);
}
<download | mirror | development version>
Convert JavaScript code to one line bookmarklet (javascript: ...).
scriptToBookmarklet_w2k.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/scriptToBookmarklet_w2k.js

// (c) Infocatcher 2008-2011
// version 0.3.0 - 2011-12-20
// Windows 2000 SP2 +

//===================
// Convert JavaScript code to one line bookmarklet
// http://en.wikipedia.org/wiki/Bookmarklet
// http://ru.wikipedia.org/wiki/Букмарклет

// Arguments:
//   -saveSpaces=0         - replace multiple spaces with one
//              =1         - don't replace spaces inside lines
//              =2         - only replace new lines
//   -removeNewLines=true  - remove new lines instead of replace them with space
//   -saveComments=0       - sum of flags: 1 - save block comments, 2 - save line comments

// Usage:
//   Call("Scripts::Main", 1, "converter.js")
//   Call("Scripts::Main", 1, "converter.js", "-saveSpaces=0 -removeNewLines=true -saveComments=3")
//===================

function _localize(s) {
   var strings = {
      "Code of bookmarklet (OK - copy):": {
         ru: "Код букмарклета (ОК - копировать):"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

var saveSpaces     = getArg("saveSpaces", 1);
var removeNewLines = getArg("removeNewLines", false);
var saveComments   = getArg("saveComments", 0);

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
   scriptToBookmarklet();

function scriptToBookmarklet() {
   var txt = getText();

   if(!(saveComments & 1))
      txt = txt.replace(/\/\*[\s\S]*\*\//g, ""); // /*comment*/

   if(!(saveComments & 2)) {
      var lines = txt.split("\r");
      for(var i = 0, l = lines.length; i < l; i++)
         lines[i] = lines[i].replace(/(^|[\t ]+|([^:\\]))\/\/[^\n\r]*$/, "$2"); // //comment
      txt = lines.join("\r");
   }
   else {
      // //comment -> /*comment*/
      var lines = txt.split("\r");
      for(var i = 0, l = lines.length; i < l; i++)
         lines[i] = lines[i].replace(/(^|[\t ]+|[^:\\])\/\/([ \t]?)[ \t]*([^\n\r]*)$/, "$1/*$2$3*/");
      txt = lines.join("\r")
         .replace(/\*\/[\n\r]+\/\*/g, "");
   }

   var newLinesReplacement = removeNewLines ? "" : " ";

   txt = txt
      .replace(/^\s*javascript:\s*/i, "")
      .replace(/^\s+|\s+$/g, "");

   if(saveSpaces == 0)
      txt = txt.replace(/[\n\r\t\s]+/g, " ");
   else if(saveSpaces == 1)
      txt = txt
         .replace(/^[ \t]+|[ \t]+$/mg, "")
         .replace(/[\n\r]+/g, newLinesReplacement);
   else if(saveSpaces >= 2)
      txt = txt.replace(/[\n\r]+/g, newLinesReplacement);

   if(
      !/^\(function\s*\(\)\s*\{.+\}\)\s*\(\);?$/.test(txt) // (function(){ ... })();
      && !/^alert\s*\(([^()]*\([^()]+\))*[^()]*\);?$/.test(txt) // alert( ... );
      && !/\Walert\s*\(\s*[^)]+\s*\);?$/.test(txt) // ... alert(x);
   )
      txt += " void(0);";

   txt = "javascript: " + txt;

   txt = AkelPad.InputBox(
      hMainWnd,
      WScript.ScriptName,
      _localize("Code of bookmarklet (OK - copy):"),
      txt
   );
   if(txt)
      AkelPad.SetClipboardText(txt);
}
function getText() {
   // Get selection or all text
   var txt = AkelPad.GetSelText();
   if(txt)
      return txt;
   if(typeof AkelPad.GetTextRange != "undefined")
      return AkelPad.GetTextRange(0, -1);
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(lpPoint) {
      setRedraw(hWndEdit, false);
      AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

      var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
      var ss = AkelPad.GetSelStart();
      var se = AkelPad.GetSelEnd();

      AkelPad.SetSel(0, -1);
      txt = AkelPad.GetSelText();

      AkelPad.SetSel(ss, se);
      columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

      AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
      AkelPad.MemFree(lpPoint);
      setRedraw(hWndEdit, true);
   }
   return txt;
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getArg(argName, defaultVal) {
   var args = {};
   for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
      if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
         args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
   getArg = function(argName, defaultVal) {
      argName = argName.toLowerCase();
      return typeof args[argName] == "undefined" // argName in args
         ? defaultVal
         : args[argName];
   };
   return getArg(argName, defaultVal);
}
<download | mirror | development version>
For old JScript versions.

textStatistics.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/textStatistics.js

// (c) Infocatcher 2008-2011
// version 0.3.4 - 2011-12-20

// Usage:
//   Call("Scripts::Main", 1, "textStatistics.js")

// Windows XP+ (?)

function _localize(s) {
   var strings = {
      "Text missing!": {
         ru: "Текст отсутствует!"
      },
      "Lines: ": {
         ru: "Строки: "
      },
      "Only spaces: ": {
         ru: "Только пробельные символы: "
      },
      "Empty: ": {
         ru: "Пустые: "
      },
      "Shortest line: #": {
         ru: "Самая короткая строка: №"
      },
      "Longest line: #": {
         ru: "Самая длинная строка: №"
      },
      "Length: ": {
         ru: "Длина: "
      },
      "Line: “%S”": {
         ru: "Строка: «%S»"
      },
      "Symbols: ": {
         ru: "Символы: "
      },
      "Cyrillic: ": {
         ru: "Кириллица: "
      },
      "Latin: ": {
         ru: "Латиница: "
      },
      "Digits: ": {
         ru: "Цифры: "
      },
      "Space symbols: ": {
         ru: "Пробельные символы: "
      },
      "Spaces: ": {
         ru: "Пробелы: "
      },
      "Tabs: ": {
         ru: "Табуляции: "
      },
      "Carriage returns (\\r): ": {
         ru: "Возвраты каретки (\\r): "
      },
      "Line feeds (\\n): ": {
         ru: "Переводы строки (\\n): "
      },
      "Words: ": {
         ru: "Слова: "
      },
      "Cyrillic: ": {
         ru: "Кириллица: "
      },
      "Latin: ": {
         ru: "Латиница: "
      },
      "Numbers: ": {
         ru: "Числа: "
      },
      "Decimal: ": {
         ru: "Десятичные: "
      },
      "Hexadecimal: ": {
         ru: "Шестнадцатеричные: "
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
   showTextStatistics();

function showTextStatistics() {
   var res = getTextStatistics();
   AkelPad.MessageBox(hMainWnd, res, WScript.ScriptName, 64 /*MB_ICONINFORMATION*/);
}
function getTextStatistics() {
   var txt = getText();
   if(!txt)
      return _localize("Text missing!");
   var txtn = txt.replace(/\r\n|\n\r|\n|\r/g, "\n"); // Strange things happens with \r\n
   var cFile = AkelPad.GetEditFile(0);
   var res = cFile ? cFile + ":\n\n" : "";

   res +=          _localize("Lines: ")       + formatNum(countOf(txt, /\r\n|\n\r|\n|\r/g) + 1) + "\n";
   res += "  – " + _localize("Only spaces: ") + formatNum(countOf(txt, /^[\t ]+$/mg)) + "\n";
   res += "  – " + _localize("Empty: ")       + formatNum(countOf(txtn, /^$/mg)) + "\n";

   res += "\n";

   var longestLine  = -1,       longestLineNum,  longestLineText;
   var shortestLine = Infinity, shortestLineNum, shortestLineText;
   var lines = txtn.split("\n");
   var curLine, curLen;
   var tabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0) || 8;
   for(var i = 0, l = lines.length; i < l; i++) {
      curLine = lines[i];
      curLen = curLine.length;

      if(curLine.indexOf("\t") != -1) {
         var tabWidth, dw;
         for(var j = 0, column = 0, ll = curLen; j < ll; j++, column++) {
            if(curLine.charAt(j) != "\t")
               continue;
            tabWidth = tabStop - column % tabStop;
            if(tabWidth <= 1)
               continue;
            dw = tabWidth - 1;
            curLen += dw;
            column += dw;
         }
      }

      if(curLen > longestLine) {
         longestLine = curLen;
         longestLineNum = i + 1;
         longestLineText = curLine;
      }
      if(curLen < shortestLine) {
         shortestLine = curLen;
         shortestLineNum = i + 1;
         shortestLineText = curLine;
      }
   }

   res +=          _localize("Longest line: #") + formatNum(longestLineNum) + "\n";
   res += "  – " + _localize("Length: ") + formatNum(longestLine) + "\n";
   res += "  – " + _localize("Line: “%S”").replace("%S", formatLine(longestLineText)) + "\n";
   res +=          _localize("Shortest line: #") + formatNum(shortestLineNum) + "\n";
   res += "  – " + _localize("Length: ") + formatNum(shortestLine) + "\n";
   res += "  – " + _localize("Line: “%S”").replace("%S", formatLine(shortestLineText)) + "\n";

   res += "\n";

   res +=             _localize("Symbols: ")                + formatNum(txt.length) + "\n";
   res += "  – "    + _localize("Cyrillic: ")               + formatNum(countOf(txt, /[а-яё]/ig)) + "\n";
   res += "  – "    + _localize("Latin: ")                  + formatNum(countOf(txt, /[a-z]/ig)) + "\n";
   res += "  – "    + _localize("Digits: ")                 + formatNum(countOf(txt, /\d/g)) + "\n";
   res += "  – "    + _localize("Space symbols: ")          + formatNum(countOf(txt, /\s/g)) + "\n";
   res += "     = " + _localize("Spaces: ")                 + formatNum(countOf(txt, / /g)) + "\n";
   res += "     = " + _localize("Tabs: ")                   + formatNum(countOf(txt, /\t/g)) + "\n";
   res += "     = " + _localize("Carriage returns (\\r): ") + formatNum(countOf(txt, /\r/g)) + "\n";
   res += "     = " + _localize("Line feeds (\\n): ")       + formatNum(countOf(txt, /\n/g)) + "\n";

   res += "\n";

   var wordsCyr = countOf(txt, /[а-яё]+(-[а-яё]+)*/ig);
   var wordsLat = countOf(txt, /[a-z]+(-[a-z]+)*('[st])?/ig);
   res +=          _localize("Words: ")    + formatNum(wordsCyr + wordsLat) + "\n";
   res += "  – " + _localize("Cyrillic: ") + formatNum(wordsCyr) + "\n";
   res += "  – " + _localize("Latin: ")    + formatNum(wordsLat) + "\n";

   res += "\n";

   var numsDec = countOf(txt, /(^|\W)\d+([.,]\d+)?(?=(\W|$))/g); // Be careful with numbers like "0,2"
   var numsHex = countOf(txt, /(^|\W)0x[\da-f]+(?=(\W|$))/ig);
   res +=          _localize("Numbers: ")     + formatNum(numsDec + numsHex) + "\n";
   res += "  – " + _localize("Decimal: ")     + formatNum(numsDec) + "\n";
   res += "  – " + _localize("Hexadecimal: ") + formatNum(numsHex) + "\n";

   return res;
}
function countOf(txt, regexp) {
   var m = txt.match(regexp);
   return m ? m.length : 0;
}
function formatNum(n) {
   return String(n).replace(/(\d)(?=(\d{3})+(\D|$))/g, "$1 ");
}
function formatLine(s) {
   var maxLength = 45;
   var tabWidth = 8;
   var tab = new Array(tabWidth + 1).join(" ");
   var ret = s.substr(0, maxLength);
   while(ret.replace(/\t/g, tab).length > maxLength)
      ret = ret.substr(0, ret.length - 1);
   return ret == s
      ? ret
      : ret + "\u2026"; // "..."
}

function getText() {
   // Get selection or all text
   var txt = AkelPad.GetSelText(4 - AkelPad.GetEditNewLine(0));
   if(txt)
      return txt;
   if(typeof AkelPad.GetTextRange != "undefined")
      return AkelPad.GetTextRange(0, -1, 4 - AkelPad.GetEditNewLine(0));
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return "";
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
   var ss = AkelPad.GetSelStart();
   var se = AkelPad.GetSelEnd();

   AkelPad.SetSel(0, -1);
   txt = AkelPad.GetSelText(4 - AkelPad.GetEditNewLine(0));

   AkelPad.SetSel(ss, se);
   columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   AkelPad.MemFree(lpPoint);
   setRedraw(hWndEdit, true);
   return txt;
}

function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | mirror | development version>
Provide some statistic for English and Russian texts.

undoRedoAll.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/undoRedoAll.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/undoRedoAll.js

// (c) Infocatcher 2010, 2014
// version 0.1.1 - 2014-04-04

// Arguments:
//   -mode=0       - undo
//   -mode=1       - redo
//   -stopOnSaved

// Usage:
//   Call("Scripts::Main", 1, "undoRedoAll.js", "-mode=0 -stopOnSaved=true")

var AEM_CANUNDO = 3075;
var AEM_CANREDO = 3076;
var AEM_UNDO    = 3077;
var AEM_REDO    = 3078;

var MODE_UNDO = 0;
var MODE_REDO = 1;

// Read arguments:
var mode        = AkelPad.GetArgValue("mode", MODE_UNDO);
var stopOnSaved = AkelPad.GetArgValue("stopOnSaved", false);

var CAN_ACTION = AEM_CANUNDO;
var ACTION     = AEM_UNDO;
if(mode == MODE_REDO) {
   CAN_ACTION = AEM_CANREDO;
   ACTION     = AEM_REDO;
}

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(
   AkelPad.GetMainWnd()
   && AkelPad.IsAkelEdit()
   && canAction()
) {
   var nFirstLine = saveLineScroll(hWndEdit);

   do action();
   while(canAction());

   restoreLineScroll(hWndEdit, nFirstLine);
}
function canAction() {
   return (stopOnSaved ? AkelPad.SendMessage(hWndEdit, 3086 /*AEM_GETMODIFY*/, 0, 0) : true)
      && AkelPad.SendMessage(hWndEdit, CAN_ACTION, 0, 0);
}
function action() {
   AkelPad.SendMessage(hWndEdit, ACTION, 0, 0);
}

// From Instructor's SearchReplace.js
function saveLineScroll(hWnd)
{
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, false, 0);
   return AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0);
}
function restoreLineScroll(hWnd, nBeforeLine)
{
   if (AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0) != nBeforeLine)
   {
      var lpScrollPos;
      var nPosY=AkelPad.SendMessage(hWnd, 3198 /*AEM_VPOSFROMLINE*/, 0 /*AECT_GLOBAL*/, nBeforeLine);

      if (lpScrollPos=AkelPad.MemAlloc(_X64?16:8 /*sizeof(POINT64)*/))
      {
         AkelPad.MemCopy(lpScrollPos + 0 /*offsetof(POINT64, x)*/, -1, 2 /*DT_QWORD*/);
         AkelPad.MemCopy(lpScrollPos + (_X64?8:4) /*offsetof(POINT64, y)*/, nPosY, 2 /*DT_QWORD*/);
         AkelPad.SendMessage(hWnd, 3180 /*AEM_SETSCROLLPOS*/, 0, lpScrollPos);
         AkelPad.MemFree(lpScrollPos);
      }
   }
   AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, true, 0);
   oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | mirror | development version>


Last edited by Infocatcher on Fri Apr 04, 2014 12:58 pm; edited 19 times in total
Back to top
View user's profile Send private message
KDJ



Joined: 06 Mar 2010
Posts: 1263
Location: Poland

PostPosted: Sun Nov 14, 2010 7:22 pm    Post subject: Reply with quote

One-dimensional text array sorting function:
ArrayTextSort_example.js

Code:
// One-dimensional text array sorting function - 2010-12-18
//
// Sorted by key from nStart to nEnd character in string.
// This function changes the original array.
// Here is an example of use:

var aArray = ["ZZZdddaaa",
              "456aaa0xAcla",
              "999ZZZ0xF"];

ArrayTextSort(aArray, 9, 10, 1, 0, 0)

WScript.Echo("Sorted array:" + "\n" + aArray[0] + "\n" + aArray[1] + "\n" + aArray[2]);


////////////////////////////////////////////////
function ArrayTextSort(aArr, nStart, nEnd, bDescending, bNumerical, bIgnoreCase)
{
  if (bNumerical)
  {
    if (bDescending)
    {
      aArr.sort(function(a, b) {
        if      (Number(a.substring(nStart, nEnd)) < Number(b.substring(nStart, nEnd))) return 1;
        else if (Number(a.substring(nStart, nEnd)) > Number(b.substring(nStart, nEnd))) return -1;
        else return 0; });
    }
    else
    {
      aArr.sort(function(a, b) {
        if      (Number(a.substring(nStart, nEnd)) < Number(b.substring(nStart, nEnd))) return -1;
        else if (Number(a.substring(nStart, nEnd)) > Number(b.substring(nStart, nEnd))) return 1;
        else return 0; });
    }
  }
  else
  {
    if (bDescending)
    {
      if (bIgnoreCase)
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd).toUpperCase() < b.substring(nStart, nEnd).toUpperCase()) return 1;
          else if (a.substring(nStart, nEnd).toUpperCase() > b.substring(nStart, nEnd).toUpperCase()) return -1;
          else return 0; });
      }
      else
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd) < b.substring(nStart, nEnd)) return 1;
          else if (a.substring(nStart, nEnd) > b.substring(nStart, nEnd)) return -1;
          else return 0; });
      }
    }
    else
    {
      if (bIgnoreCase)
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd).toUpperCase() < b.substring(nStart, nEnd).toUpperCase()) return -1;
          else if (a.substring(nStart, nEnd).toUpperCase() > b.substring(nStart, nEnd).toUpperCase()) return 1;
          else return 0; });
      }
      else
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd) < b.substring(nStart, nEnd)) return -1;
          else if (a.substring(nStart, nEnd) > b.substring(nStart, nEnd)) return 1;
          else return 0; });
      }
    }
  }
}



One or two-dimensional array sorting function:
Array2DSort_example.js

Code:
// One or two-dimensional array sorting function - 2010-12-18
//
// Sorted by any field, ascending or descending order, by numbers or by strings.
// This function changes the original array.
// Here is an example of use:

// nField      0      1      2
var aArray = [["ZZZ", "ddd", "aaa"],
              ["999", "ZZZ", "0xF"],
              ["456", "aaa", "0xA"]];

Array2DSort(aArray, 0, 0, 1, 1)

WScript.Echo("Sorted array:" + "\n" + aArray[0] + "\n" + aArray[1] + "\n" + aArray[2]);

////////////////////////////////////////////////
// If nField < 0 - must be one-dimensional array
////////////////////////////////////////////////
function Array2DSort(aArr, nField, bDescending, bNumerical, bIgnoreCase)
{
  if (bNumerical)
  {
    if (bDescending)
    {
      if (nField < 0)
        aArr.sort(function(a, b) {
          if      (Number(a) < Number(b)) return 1;
          else if (Number(a) > Number(b)) return -1;
          else return 0; });
      else
        aArr.sort(function(a, b) {
          if      (Number(a[nField]) < Number(b[nField])) return 1;
          else if (Number(a[nField]) > Number(b[nField])) return -1;
          else return 0; });
    }
    else
    {
      if (nField < 0)
        aArr.sort(function(a, b) {
          if      (Number(a) < Number(b)) return -1;
          else if (Number(a) > Number(b)) return 1;
          else return 0; });
      else
        aArr.sort(function(a, b) {
          if      (Number(a[nField]) < Number(b[nField])) return -1;
          else if (Number(a[nField]) > Number(b[nField])) return 1;
          else return 0; });
    }
  }
  else
  {
    if (bDescending)
    {
      if (bIgnoreCase)
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a).toUpperCase() < String(b).toUpperCase()) return 1;
            else if (String(a).toUpperCase() > String(b).toUpperCase()) return -1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]).toUpperCase() < String(b[nField]).toUpperCase()) return 1;
            else if (String(a[nField]).toUpperCase() > String(b[nField]).toUpperCase()) return -1;
            else return 0; });
      }
      else
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a) < String(b)) return 1;
            else if (String(a) > String(b)) return -1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]) < String(b[nField])) return 1;
            else if (String(a[nField]) > String(b[nField])) return -1;
            else return 0; });
      }
    }
    else
    {
      if (bIgnoreCase)
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a).toUpperCase() < String(b).toUpperCase()) return -1;
            else if (String(a).toUpperCase() > String(b).toUpperCase()) return 1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]).toUpperCase() < String(b[nField]).toUpperCase()) return -1;
            else if (String(a[nField]).toUpperCase() > String(b[nField]).toUpperCase()) return 1;
            else return 0; });
      }
      else
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a) < String(b)) return -1;
            else if (String(a) > String(b)) return 1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]) < String(b[nField])) return -1;
            else if (String(a[nField]) > String(b[nField])) return 1;
            else return 0; });
      }
    }
  }
}



Two-dimensional array transposition function:
Array2DTransp_example.js

Code:
// Two-dimensional array transposition function - 2010-12-18
//
// Here is an example of use:

var aArray = [["aaa", "bbb", "ccc"],
              ["111", "222", "333"],
              ["ddd", "eee", "fff"],
              ["444", "555", "666"],
              ["ggg", "hhh", "iii"]];

var aArray1 = Array2DTransp(aArray);

WScript.Echo("Array after transposition:" + "\n" + aArray1[0] + "\n" + aArray1[1] + "\n" + aArray1[2]);


////////////////////////////////////////////////
function Array2DTransp(aArr)
{
  var nLen1 = aArr.length;
  var nLen2 = aArr[0].length;
  var aArr2 = [];
  var i, n;

  aArr2.length = nLen2;

  for (n = 0; n < nLen2; ++n)
  {
    aArr2[n] = [];
    for (i = 0; i < nLen1; ++i)
    {
      aArr2[n].push(aArr[i][n]);
    }
  }

  return aArr2;
}



Last edited by KDJ on Sat Dec 18, 2010 9:47 pm; edited 3 times in total
Back to top
View user's profile Send private message
KDJ



Joined: 06 Mar 2010
Posts: 1263
Location: Poland

PostPosted: Thu Nov 18, 2010 7:00 pm    Post subject: Reply with quote

DateToShortLocaleString(dDate) function returns a short local date.

DateToShortLocaleString_example.js

Code:
// DateToShortLocaleString(dDate) function returns a short local date - 2010-12-02
//
// Here is an example of use:

var dToday     = new Date();
var pLongDate  = dToday.toLocaleString();
var pShortDate = DateToShortLocaleString(dToday);

WScript.Echo("Long date:  " + pLongDate + "\n" + "Short date: " + pShortDate);

////////
function DateToShortLocaleString(dDate)
{
  var DT_WORD   = 4;
  var oSys      = AkelPad.SystemFunction();
  var lpSysTime = AkelPad.MemAlloc(16 /*sizeof(SYSTEMTIME)*/);
  var lpString  = AkelPad.MemAlloc(256 * _TSIZE);
  var pDateTime;

  AkelPad.MemCopy(lpSysTime,     dDate.getFullYear(),     DT_WORD);
  AkelPad.MemCopy(lpSysTime + 2, dDate.getMonth() + 1,    DT_WORD);
  AkelPad.MemCopy(lpSysTime + 4, dDate.getDay(),          DT_WORD);
  AkelPad.MemCopy(lpSysTime + 6, dDate.getDate(),         DT_WORD);
  AkelPad.MemCopy(lpSysTime + 8, dDate.getHours(),        DT_WORD);
  AkelPad.MemCopy(lpSysTime +10, dDate.getMinutes(),      DT_WORD);
  AkelPad.MemCopy(lpSysTime +12, dDate.getSeconds(),      DT_WORD);
  AkelPad.MemCopy(lpSysTime +14, dDate.getMilliseconds(), DT_WORD);

  oSys.Call("kernel32::GetDateFormat" + _TCHAR,
            0x400, //LOCALE_USER_DEFAULT
            0x1,   //DATE_SHORTDATE
            lpSysTime,
            0,
            lpString,
            256);
  pDateTime = AkelPad.MemRead(lpString, _TSTR) + " ";

  oSys.Call("kernel32::GetTimeFormat" + _TCHAR,
            0x400, //LOCALE_USER_DEFAULT
            0x8,   //TIME_FORCE24HOURFORMAT
            lpSysTime,
            0,
            lpString,
            256);
  pDateTime += AkelPad.MemRead(lpString, _TSTR);

  AkelPad.MemFree(lpSysTime);
  AkelPad.MemFree(lpString);

  return pDateTime;
}

Back to top
View user's profile Send private message
KDJ



Joined: 06 Mar 2010
Posts: 1263
Location: Poland

PostPosted: Wed Dec 08, 2010 10:13 pm    Post subject: Reply with quote

This function retrieves columnar text, without selecting.

GetTextRangeColumn_example.js

Code:
// GetTextRangeColumn() function returns columnar text, without selecting - 2011-01-15
//
// Example of use:

var Txt = GetTextRangeColumn([0, 3], [6, 12], 1, 1, 1);
AkelPad.Command(4101);
AkelPad.ReplaceSel(Txt);

/////////////////////////////////////////////
// aBeg = [nBeginLine, nBeginColumn]
// aEnd = [nEndLine,   nEndColumn]
// Optional:
// bReturnText = 0 //return array of lines (default)
//               1 //return text
// nNewLine = 1  //"\r" new line (default)
//            2  //"\n" new line
//            3  //"\r\n" new line
// bFillSpaces = 0 //(default)
//               1 //fill empties with spaces
/////////////////////////////////////////////
function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var hEditWnd  = AkelPad.GetEditWnd();
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

   nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
   nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
   nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}



Last edited by KDJ on Sat Jan 15, 2011 8:35 pm; edited 1 time in total
Back to top
View user's profile Send private message
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Wed Dec 15, 2010 5:07 pm    Post subject: Reply with quote

saveStoreTime.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10403#10403
// http://infocatcher.ucoz.net/js/akelpad_scripts/saveStoreTime.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/saveStoreTime.js

// (c) Infocatcher 2010-2011, 2014
// version 0.1.4 - 2014-03-03

// Save file and don't update modification time
// Based on Instructor's code: http://akelpad.sourceforge.net/forum/viewtopic.php?p=4222#4222

// Usage:
//   Call("Scripts::Main", 1, "saveStoreTime.js")

var hMainWnd = AkelPad.GetMainWnd();

if(hMainWnd) {
   var saveTime = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 148 /*MI_SAVETIME*/, 0);
   if(!saveTime)
      AkelPad.Command(4252 /*IDM_OPTIONS_SAVETIME*/);
   AkelPad.Command(4105 /*IDM_FILE_SAVE*/);
   if(!saveTime)
      AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 148 /*MIS_SAVETIME*/, saveTime);
}
<download | mirror | development version>
Temporary check “save file time” option and save current document.

goToLongestLine.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10403#10403
// http://infocatcher.ucoz.net/js/akelpad_scripts/goToLongestLine.js

// (c) Infocatcher 2010-2011
// version 0.3.9 - 2011-12-20

//===================
// Go to longest line below or above current
// Hotkeys in dialog:
//   PageUp/PageDown            - go to longest line below/above current
//   Ctrl+PageUp/Ctrl+PageDown  - go to start/end of document

// Arguments:
//   -dialog=true        - show dialog
//   -reverse=false      - inverse direction (only without dialog)
//   -timeLimit=400      - time limit (in milliseconds) for very big files
//   -close=true         - force check "close dialog"
//   -focus=true         - force check "focus editor"
//   -autoGo=true        - automatically go to longest line after run with -dialog=true
//   -saveOptions=0      - don't store options
//               =1      - save options after them usage
//               =2      - save options on exit
//   -savePosition=true  - allow store last window position

// Usage:
//   Call("Scripts::Main", 1, "goToLongestLine.js")
//   Call("Scripts::Main", 1, "goToLongestLine.js", "-dialog=false -reverse=false")
//   Call("Scripts::Main", 1, "goToLongestLine.js", "-dialog=true -close=true -saveOptions=0 -savePosition=false")
//===================

function _localize(s) {
   var strings = {
      "&Close dialog": {
         ru: "&Закрывать диалог"
      },
      "&Focus editor": {
         ru: "Переводить &фокус на редактор"
      },
      "&Time limit:": {
         ru: "&Ограничение по времени:"
      },
      "ms": {
         ru: "мс"
      },
      "Are you sure to disable time limit?": {
         ru: "Вы уверены, что хотите отключить ограничение по времени?"
      },
      "Time limit is too big (%S min)!\nContinue anyway?": {
         ru: "Ограничение по времени слишком велико (%S мин)\nВсе равно продолжить?"
      },
      "&Line:": {
         ru: "&Строка:"
      },
      "L&ength:": {
         ru: "&Длина:"
      },
      "&Processed:": {
         ru: "&Обработано:"
      },
      "&Down": {
         ru: "В&низ"
      },
      "&Up": {
         ru: "В&верх"
      },
      "Cancel": {
         ru: "Отмена"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}


// Read arguments:
// getArg(argName, defaultValue), getArgOrPref(argAndPrefName, type, defaultValue)
var saveOptions  = getArg("saveOptions", 1);
var savePosition = getArg("savePosition", true);

if(saveOptions || savePosition)
   var prefs = new Prefs();

var dialog       = getArg("dialog", true);
var reverse      = getArg("reverse", false);
var autoGo       = getArg("autoGo", false);
var checkClose   = getArgOrPref("close",     prefs && prefs.DWORD);
var checkFocus   = getArgOrPref("focus",     prefs && prefs.DWORD);
var timeLimit    = getArgOrPref("timeLimit", prefs && prefs.DWORD, 400);

prefs && prefs.end();


var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

Number.prototype._origToFixed = Number.prototype.toFixed;
Number.prototype.toFixed = function(r) {
   if(r >= 0 && this._origToFixed)
      return this._origToFixed(r);
   var n = this;
   var d = Math.pow(10, r);
   n = (Math.round(n*d)/d).toString();
   if(r <= 0)
      return n;
   if(!/\./.test(n))
      n += ".";
   var count = n.match(/\.(.*)$/)[1].length;
   n += new Array(r - count + 1).join("0");
   return n;
};

if(hMainWnd) {
   if(dialog)
      goToLongestLineDialog();
   else
      goToLongestLine(reverse);
}

function goToLongestLine(reverse) {
   var hWndEdit = AkelPad.GetEditWnd();

   var ww = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
   if(ww) {
      setRedraw(hWndEdit, false);
      AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
   }

   var longestLine;
   var longestLineLength = -1;
   var line, lineStart, lineLength, lineEnd;
   var indx;
   var linesCount = AkelPad.SendMessage(hWndEdit, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
   var count;
   var ss = AkelPad.GetSelStart();
   line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, ss);
   if(reverse) {
      lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
      indx       = lineStart - 1;

      count = line;
   }
   else {
      lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
      lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, ss, 0);
      lineEnd    = lineStart + lineLength;
      indx       = lineEnd + 1;

      count = linesCount - line - 1;
   }

   if(timeLimit)
      var stopTime = new Date().getTime() + timeLimit;
   var lines = 0;
   var tabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0) || 8;
   for(;;) {
      if(reverse) {
         if(--line == -1)
            break;
         lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
         lineEnd    = indx;
         lineLength = lineEnd - lineStart;
      }
      else {
         if(++line == linesCount)
            break;
         lineStart  = indx;
         lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, indx, 0);
         lineEnd    = lineStart + lineLength;
      }
      lines++;

      var lineText = AkelPad.GetTextRange(lineStart, lineEnd);
      if(lineText.indexOf("\t") != -1) {
         for(var i = 0, column = 0, ll = lineLength; i < ll; i++, column++) {
            if(lineText.charAt(i) != "\t")
               continue;
            var tabWidth = tabStop - column % tabStop;
            if(tabWidth <= 1)
               continue;
            var dw = tabWidth - 1;
            lineLength += dw;
            column     += dw;
         }
      }

      if(lineLength > longestLineLength) {
         longestLineLength = lineLength;
         longestLine = line;
      }
      if(timeLimit && new Date().getTime() > stopTime)
         break;
      indx = reverse
         ? lineStart - 1
         : lineEnd   + 1;
   }

   if(ww) {
      AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
      setRedraw(hWndEdit, true);
   }

   if(longestLine != undefined) {
      var gotoStr = (longestLine + 1) + ":" + (longestLineLength + 1);
      AkelPad.SendMessage(hMainWnd, 1206 /*AKD_GOTOW*/, 0x1 /*GT_LINE*/, AkelPad.MemStrPtr(gotoStr));
   }
   return {
      line:        (longestLine == undefined ? line : longestLine) + 1,
      lineLength:  longestLineLength,
      linesCount:  linesCount,
      processed:   lines,
      targetCount: lines ? count : 0
   };
}

function goToLongestLineDialog(modal) {
   var hInstanceDLL = AkelPad.GetInstanceDll();
   var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");

   var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
   if(hWndDialog) {
      if(oSys.Call("user32::IsIconic", hWndDialog))
         oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
      AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
      return;
   }

   if(
      !AkelPad.WindowRegisterClass(dialogClass)
      && ( // Previous script instance crashed
         !AkelPad.WindowUnregisterClass(dialogClass)
         || !AkelPad.WindowRegisterClass(dialogClass)
      )
   )
      return;

   var disabled = false;
   var disabledTimeout = 150;

   var IDC_STATIC     = -1;
   var IDC_FOCUS      = 1001;
   var IDC_CLOSE      = 1002;
   var IDC_TIME_LIMIT = 1003;
   var IDC_LINE       = 1004;
   var IDC_LENGTH     = 1005;
   var IDC_PROCESSED  = 1006;
   var IDC_UP         = 1007;
   var IDC_DOWN       = 1008;
   var IDC_CANCEL     = 1009;

   var hWndFocus, hWndClose;
   var hWndStatic, hWndTimeLimit, hWndLine, hWndLength, hWndProcessed;
   var hWndDown, hWndUp, hWndCancel;

   var scale = new Scale(0, hMainWnd);
   var sizeNonClientX = oSys.Call("user32::GetSystemMetrics", 7 /*SM_CXFIXEDFRAME*/) * 2;
   var sizeNonClientY = oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/) * 2 + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);

   // Create dialog
   hWndDialog = oSys.Call(
      "user32::CreateWindowEx" + _TCHAR,
      0,                             //dwExStyle
      dialogClass,                   //lpClassName
      0,                             //lpWindowName
      0x90CA0000,                    //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
      scale.x(0),                    //x
      scale.y(0),                    //y
      scale.x(286) + sizeNonClientX, //nWidth
      scale.y(193) + sizeNonClientY, //nHeight
      hMainWnd,                      //hWndParent
      0,                             //ID
      hInstanceDLL,                  //hInstance
      dialogCallback                 //Script function callback. To use it class must be registered by WindowRegisterClass.
   );
   if(!hWndDialog)
      return;

   function dialogCallback(hWnd, uMsg, wParam, lParam) {
      switch(uMsg) {
         case 1: //WM_CREATE
            function setWindowFontAndText(hWnd, hFont, pText) {
               AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
               windowText(hWnd, pText);
            }

            var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);

            // Dialog caption
            windowText(hWnd, dialogTitle);

            // Checkbox: close dialog
            hWndClose = createWindowEx(
               0,             //dwExStyle
               "BUTTON",      //lpClassName
               0,             //lpWindowName
               0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
               12,            //x
               12,            //y
               270,           //nWidth
               16,            //nHeight
               hWnd,          //hWndParent
               IDC_CLOSE,     //ID
               hInstanceDLL,  //hInstance
               0              //lpParam
            );
            setWindowFontAndText(hWndClose, hGuiFont, _localize("&Close dialog"));
            checked(hWndClose, checkClose);

            // Checkbox: focus editor
            hWndFocus = createWindowEx(
               0,             //dwExStyle
               "BUTTON",      //lpClassName
               0,             //lpWindowName
               0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
               12,            //x
               34,            //y
               270,           //nWidth
               16,            //nHeight
               hWnd,          //hWndParent
               IDC_FOCUS,     //ID
               hInstanceDLL,  //hInstance
               0              //lpParam
            );
            setWindowFontAndText(hWndFocus, hGuiFont, _localize("&Focus editor"));
            checked(hWndFocus, checkFocus);

            // Static window: time limit label
            hWndStatic = createWindowEx(
               0,            //dwExStyle
               "STATIC",     //lpClassName
               0,            //lpWindowName
               0x50000000,   //WS_VISIBLE|WS_CHILD
               12,           //x
               59,           //y
               134,          //nWidth
               13,           //nHeight
               hWnd,         //hWndParent
               IDC_STATIC,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Time limit:"));

            // Edit: time limit
            hWndTimeLimit = createWindowEx(
               0x200,          //WS_EX_CLIENTEDGE
               "EDIT",         //lpClassName
               0,              //lpWindowName
               0x50012080,     //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_NUMBER|ES_AUTOHSCROLL
               150,            //x
               56,             //y
               60,             //nWidth
               19,             //nHeight
               hWnd,           //hWndParent
               IDC_TIME_LIMIT, //ID
               hInstanceDLL,   //hInstance
               0               //lpParam
            );
            setWindowFontAndText(hWndTimeLimit, hGuiFont, String(timeLimit));

            // Up/down buttons
            hWndStatic = createWindowEx(
               0,                 //dwExStyle
               "msctls_updown32", //lpClassName
               0,                 //lpWindowName
               0x500000A2,        //WS_VISIBLE|WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_NOTHOUSANDS
               210,               //x
               55,                //y
               16,                //nWidth
               21,                //nHeight
               hWnd,              //hWndParent
               IDC_STATIC,        //ID
               hInstanceDLL,      //hInstance
               0                  //lpParam
            );
            AkelPad.SendMessage(hWndStatic, 0x0400 + 105 /*UDM_SETBUDDY*/, hWndTimeLimit, 0);
            AkelPad.SendMessage(hWndStatic, 0x0400 + 101 /*UDM_SETRANGE*/, 0, ((0 & 0xFFFF) << 16) + (30000 & 0xFFFF));

            // Static window: time limit ms label
            hWndStatic = createWindowEx(
               0,            //dwExStyle
               "STATIC",     //lpClassName
               0,            //lpWindowName
               0x50000000,   //WS_VISIBLE|WS_CHILD
               230,          //x
               59,           //y
               58,           //nWidth
               13,           //nHeight
               hWnd,         //hWndParent
               IDC_STATIC,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndStatic, hGuiFont, _localize("ms"));

            // Static window: line label
            hWndStatic = createWindowEx(
               0,            //dwExStyle
               "STATIC",     //lpClassName
               0,            //lpWindowName
               0x50000000,   //WS_VISIBLE|WS_CHILD
               12,           //x
               89,           //y
               78,           //nWidth
               13,           //nHeight
               hWnd,         //hWndParent
               IDC_STATIC,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Line:"));

            // Edit: line
            hWndLine = createWindowEx(
               0x200,        //WS_EX_CLIENTEDGE
               "EDIT",       //lpClassName
               0,            //lpWindowName
               0x50010880,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
               94,           //x
               86,           //y
               180,          //nWidth
               19,           //nHeight
               hWnd,         //hWndParent
               IDC_LINE,     //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndLine, hGuiFont, "");

            // Static window: length label
            hWndStatic = createWindowEx(
               0,            //dwExStyle
               "STATIC",     //lpClassName
               0,            //lpWindowName
               0x50000000,   //WS_VISIBLE|WS_CHILD
               12,           //x
               110,          //y
               78,           //nWidth
               13,           //nHeight
               hWnd,         //hWndParent
               IDC_STATIC,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndStatic, hGuiFont, _localize("L&ength:"));

            // Edit: length
            hWndLength = createWindowEx(
               0x200,        //WS_EX_CLIENTEDGE
               "EDIT",       //lpClassName
               0,            //lpWindowName
               0x50010880,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
               94,           //x
               107,          //y
               180,          //nWidth
               19,           //nHeight
               hWnd,         //hWndParent
               IDC_LENGTH,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndLength, hGuiFont, "");

            // Static window: processed lines label
            hWndStatic = createWindowEx(
               0,            //dwExStyle
               "STATIC",     //lpClassName
               0,            //lpWindowName
               0x50000000,   //WS_VISIBLE|WS_CHILD
               12,           //x
               131,          //y
               78,           //nWidth
               13,           //nHeight
               hWnd,         //hWndParent
               IDC_STATIC,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Processed:"));

            // Edit: processed lines
            hWndProcessed = createWindowEx(
               0x200,         //WS_EX_CLIENTEDGE
               "EDIT",        //lpClassName
               0,             //lpWindowName
               0x50010880,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
               94,            //x
               128,           //y
               180,           //nWidth
               19,            //nHeight
               hWnd,          //hWndParent
               IDC_PROCESSED, //ID
               hInstanceDLL,  //hInstance
               0              //lpParam
            );
            setWindowFontAndText(hWndProcessed, hGuiFont, "");

            // Down button window
            hWndDown = createWindowEx(
               0,            //dwExStyle
               "BUTTON",     //lpClassName
               0,            //lpWindowName
               0x50010001,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
               12,           //x
               159,          //y
               80,           //nWidth
               23,           //nHeight
               hWnd,         //hWndParent
               IDC_DOWN,     //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndDown, hGuiFont, _localize("&Down"));

            // Up button window
            hWndUp = createWindowEx(
               0,            //dwExStyle
               "BUTTON",     //lpClassName
               0,            //lpWindowName
               0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
               104,          //x
               159,          //y
               80,           //nWidth
               23,           //nHeight
               hWnd,         //hWndParent
               IDC_UP,       //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndUp, hGuiFont, _localize("&Up"));

            // Cancel button window
            hWndCancel = createWindowEx(
               0,            //dwExStyle
               "BUTTON",     //lpClassName
               0,            //lpWindowName
               0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
               196,          //x
               159,          //y
               80,           //nWidth
               23,           //nHeight
               hWnd,         //hWndParent
               IDC_CANCEL,   //ID
               hInstanceDLL, //hInstance
               0             //lpParam
            );
            setWindowFontAndText(hWndCancel, hGuiFont, _localize("Cancel"));

            oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CLOSE, 0);

            //centerWindow(hWnd);
            //centerWindow(hWnd, hMainWnd);
            restoreWindowPosition(hWnd, hMainWnd);

            //autoGo && oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
            if(autoGo) try {
               controlsEnabled(false);
               var document = new ActiveXObject("htmlfile");
               var window = document.parentWindow;
               window.setTimeout(function() {
                  oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
               }, 0);
            }
            catch(e) {
               oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
            }
         break;
         case 7: //WM_SETFOCUS
            focusWindow(hWndDown);
         break;
         case 256: //WM_KEYDOWN
            var ctrl = oSys.Call("user32::GetAsyncKeyState", 162 /*VK_LCONTROL*/)
               || oSys.Call("user32::GetAsyncKeyState", 163 /*VK_RCONTROL*/);
            var shift = oSys.Call("user32::GetAsyncKeyState", 160 /*VK_LSHIFT*/)
               || oSys.Call("user32::GetAsyncKeyState", 161 /*VK_RSHIFT*/);

            if(wParam == 27 /*VK_ESCAPE*/)
               oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
            else if((ctrl || shift) && wParam == 34 /*PageDown*/) {
               AkelPad.SetSel(-1, -1);
               checked(hWndFocus) && focusWindow(AkelPad.GetEditWnd());
            }
            else if((ctrl || shift) && wParam == 33 /*PageUp*/) {
               AkelPad.SetSel(0, 0);
               checked(hWndFocus) && focusWindow(AkelPad.GetEditWnd());
            }
            else if(wParam == 13 /*VK_RETURN*/ || wParam == 34 /*PageDown*/)
               oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_DOWN, 0);
            else if(wParam == 33 /*PageUp*/)
               oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_UP, 0);
         break;
         case 273: //WM_COMMAND
            var idc = wParam & 0xffff;
            switch(idc) {
               case IDC_DOWN:
               case IDC_UP:
                  if(!readTimeLimit())
                     break;

                  if(disabled == true || disabled > new Date().getTime())
                     break;
                  disabled = true;
                  var up = idc == IDC_UP;
                  var hWndFocused = oSys.Call("user32::GetFocus");
                  controlsEnabled(false);
                  var stats = goToLongestLine(up);

                  windowText(hWndLine, formatNum(stats.line) + " / " + formatNum(stats.linesCount));
                  windowText(hWndLength, formatNum(stats.lineLength));
                  windowText(
                     hWndProcessed,
                     stats.processed == stats.targetCount
                        ? formatNum(stats.processed)
                        : formatNum(stats.processed) + " / " + formatNum(stats.targetCount)
                         + " (" + toLocaleNum((stats.processed/stats.targetCount*100).toFixed(2)) + "%)"
                  );

                  var closeDlg    = checked(hWndClose);
                  var focusEditor = checked(hWndFocus);
                  if(saveOptions == 1) {
                     prefs.set({
                        close:     closeDlg,
                        focus:     focusEditor,
                        timeLimit: timeLimit
                     });
                     prefs.end();
                  }
                  if(closeDlg)
                     closeDialog();
                  else {
                     controlsEnabled(true);
                     if(focusEditor)
                        focusWindow(AkelPad.GetEditWnd());
                     else if(!oSys.Call("user32::GetFocus")) // We disable focused window
                        focusWindow(hWndFocused);
                     disabled = new Date().getTime() + disabledTimeout;
                  }
               break;
               case IDC_CANCEL:
                  closeDialog();
               break;
               case IDC_CLOSE:
                  enabled(hWndFocus, !checked(hWndClose));
            }
         break;
         case 16: //WM_CLOSE
            enabled(hMainWnd, true); // Enable main window
            savePosition && !oSys.Call("user32::IsIconic", hWnd) && saveWindowPosition(hWnd);
            if(saveOptions == 2) {
               prefs.set({
                  close:     checked(hWndClose),
                  focus:     checked(hWndFocus),
                  timeLimit: parseInt(windowText(hWndTimeLimit), 10) || 0
               });
               prefs.end();
            }

            oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
         break;
         case 2: //WM_DESTROY
            oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
      }
      return 0;
   }
   function saveWindowPosition(hWnd) {
      var rcWnd = getWindowRect(hWnd);
      if(!rcWnd)
         return;
      prefs.set({
         windowLeft: rcWnd.left,
         windowTop:  rcWnd.top
      });
      prefs.end();
   }
   function restoreWindowPosition(hWnd, hWndParent) {
      if(savePosition) {
         var dlgX = prefs.get("windowLeft", prefs.DWORD);
         var dlgY = prefs.get("windowTop",  prefs.DWORD);
         prefs.end();
      }

      if(dlgX == undefined || dlgY == undefined) {
         centerWindow(hWnd, hWndParent);
         return;
      }

      var rcWnd = getWindowRect(hWnd);
      if(!rcWnd)
         return;

      var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
      if(!lpRect)
         return;
      AkelPad.MemCopy(lpRect,      dlgX,                              3 /*DT_DWORD*/);
      AkelPad.MemCopy(lpRect + 4,  dlgY,                              3 /*DT_DWORD*/);
      AkelPad.MemCopy(lpRect + 8,  dlgX + (rcWnd.right - rcWnd.left), 3 /*DT_DWORD*/);
      AkelPad.MemCopy(lpRect + 12, dlgY + (rcWnd.top - rcWnd.bottom), 3 /*DT_DWORD*/);
      var hMonitor = oSys.Call("user32::MonitorFromRect", lpRect, 0x2 /*MONITOR_DEFAULTTONEAREST*/);

      if(hMonitor) {
         //typedef struct tagMONITORINFO {
         //  DWORD cbSize;
         //  RECT  rcMonitor;
         //  RECT  rcWork;
         //  DWORD dwFlags;
         //} MONITORINFO, *LPMONITORINFO;
         var sizeofMonitorInfo = 4 + 16 + 16 + 4;
         var lpMi = AkelPad.MemAlloc(sizeofMonitorInfo);
         if(lpMi) {
            AkelPad.MemCopy(lpMi, sizeofMonitorInfo, 3 /*DT_DWORD*/);
            oSys.Call("user32::GetMonitorInfo" + _TCHAR, hMonitor, lpMi);
            var rcWork = parseRect(lpMi + 4 + 16);
            AkelPad.MemFree(lpMi);
         }
      }
      else { //?
         oSys.Call("user32::SystemParametersInfo" + _TCHAR, 48 /*SPI_GETWORKAREA*/, 0, lpRect, 0);
         var rcWork = parseRect(lpRect);
      }
      AkelPad.MemFree(lpRect);

      if(rcWork) {
         var edge = Math.max(
            16,
            oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/)
               + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/)
         );

         var minX = rcWork.left - (rcWnd.right - rcWnd.left) + edge;
         var minY = rcWork.top;
         var maxX = rcWork.right - edge;
         var maxY = rcWork.bottom - edge;

         dlgX = Math.max(minX, Math.min(maxX, dlgX));
         dlgY = Math.max(minY, Math.min(maxY, dlgY));
      }

      oSys.Call("user32::SetWindowPos", hWnd, 0, dlgX, dlgY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
   }
   function centerWindow(hWnd, hWndParent) {
      var rcWnd = getWindowRect(hWnd);
      var rcWndParent = getWindowRect(hWndParent || oSys.Call("user32::GetDesktopWindow"));
      if(!rcWndParent || !rcWnd)
         return;
      var x = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
      var y = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
      oSys.Call("user32::SetWindowPos", hWnd, 0, x, y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
   }
   function getWindowRect(hWnd, hWndParent) {
      var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
      if(!lpRect)
         return null;
      oSys.Call("user32::GetWindowRect", hWnd, lpRect);
      hWndParent && oSys.Call("user32::ScreenToClient", hWndParent, lpRect);
      var rcWnd = parseRect(lpRect);
      AkelPad.MemFree(lpRect);
      return rcWnd;
   }
   function parseRect(lpRect) {
      return {
         left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
         top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
         right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
         bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
      };
   }
   function windowText(hWnd, pText) {
      if(arguments.length > 1)
         return oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText);
      var len = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWnd);
      var lpText = AkelPad.MemAlloc((len + 1)*_TSIZE);
      if(!lpText)
         return "";
      oSys.Call("user32::GetWindowText" + _TCHAR, hWnd, lpText, len + 1);
      pText = AkelPad.MemRead(lpText, _TSTR);
      AkelPad.MemFree(lpText);
      return pText;
   }
   function checked(hWnd, val) {
      return arguments.length == 1
         ? AkelPad.SendMessage(hWnd, 240 /*BM_GETCHECK*/, 0, 0)
         : AkelPad.SendMessage(hWnd, 241 /*BM_SETCHECK*/, val ? 1 /*BST_CHECKED*/ : 0, 0);
   }
   function enabled(hWnd, val) {
      oSys.Call("user32::EnableWindow", hWnd, val);
   }
   function focusWindow(hWnd) {
      oSys.Call("user32::SetFocus", hWnd);
   }
   function controlsEnabled(val) {
      enabled(hWndUp,   val);
      enabled(hWndDown, val);
      !modal && enabled(hMainWnd, val);
   }
   function closeDialog() {
      oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
   }
   function readTimeLimit() {
      var timeLimitMin  = 0;
      var timeLimitWarn = 15000;
      var timeLimitMax  = 24*60*60*1000;
      var tlOrig = windowText(hWndTimeLimit);
      var tl = Number(
         tlOrig
            .replace(/\D/g, "")
            .replace(/^0+/, "")
      );
      tl = Math.max(timeLimitMin, Math.min(timeLimitMax, tl));

      var confirm = function(ask) {
         if(typeof readTimeLimit._ok != "undefined" && readTimeLimit._ok)
            return true; // Only one confirmation
         return readTimeLimit._ok = AkelPad.MessageBox(
            hWndDialog, ask, dialogTitle, 33 /*MB_OKCANCEL|MB_ICONQUESTION*/
         ) == 1 /*IDOK*/;
      };
      if(!tl && !confirm(_localize("Are you sure to disable time limit?"))) {
         focusWindow(hWndTimeLimit);
         AkelPad.SendMessage(hWndTimeLimit, 177 /*EM_SETSEL*/, 0, -1);
         return false;
      }
      if(tl > timeLimitWarn) {
         var secs = Math.round(tl/1000);
         var mins = Math.floor(secs/60);
         secs = Math.floor(secs%60);
         if(secs < 10)
            secs = "0" + secs;
         if(!confirm(_localize("Time limit is too big (%S min)!\nContinue anyway?").replace("%S", mins + ":" + secs))) {
            focusWindow(hWndTimeLimit);
            AkelPad.SendMessage(hWndTimeLimit, 177 /*EM_SETSEL*/, 0, -1);
            return false;
         }
      }

      if(String(tl) != tlOrig)
         windowText(hWndTimeLimit, String(tl));
      timeLimit = tl;
      return true;
   }

   function Scale(hDC, hWnd) {
      var hNewDC = hDC || oSys.Call("user32::GetDC", hWnd);
      if(hNewDC) {
         this._x = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 88 /*LOGPIXELSX*/);
         this._y = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 90 /*LOGPIXELSY*/);

         //Align to 16 pixel
         this._x += this._x % 16;
         this._y += this._y % 16;

         !hDC && oSys.Call("user32::ReleaseDC", hWnd, hNewDC);

         this.x = function(x) {
            return oSys.Call("kernel32::MulDiv", x, this._x, 96);
         };
         this.y = function(y) {
            return oSys.Call("kernel32::MulDiv", y, this._y, 96);
         };
      }
      else {
         this.x = this.y = function(n) {
            return n;
         };
      }
   }
   function createWindowEx(
      dwExStyle, lpClassName, lpWindowName, dwStyle,
      x, y, w, h,
      hWndParent, id, hInstance, callback
   ) {
      return oSys.Call(
         "user32::CreateWindowEx" + _TCHAR,
         dwExStyle,
         lpClassName,
         lpWindowName,
         dwStyle,
         scale.x(x),
         scale.y(y),
         scale.x(w),
         scale.y(h),
         hWndParent,
         id,
         hInstance,
         callback || 0
      );
   }

   modal && enabled(hMainWnd, false); // Disable main window, to make dialog modal

   AkelPad.ScriptNoMutex(); // Allow other scripts running
   AkelPad.WindowGetMessage(); // Message loop

   AkelPad.WindowUnregisterClass(dialogClass);
}

function formatNum(n) {
   //return Number(n).toLocaleString().replace(/\s*[^\d\s\xa0\u2002\u2003\u2009].*$/, "");
   return String(n).replace(/(\d)(?=(\d{3})+(\D|$))/g, "$1\xa0");
}
function toLocaleNum(n) { // 1.25 -> 1,25
   var localeDelimiter = 1.1.toLocaleString().replace(/^\d+|\d+$/g, "");
   if(!localeDelimiter || /\d/.test(localeDelimiter))
       localeDelimiter = ".";
   return String(n).replace(/\./, localeDelimiter);
}
function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}

function getArg(argName, defaultVal) {
   var args = {};
   for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
      if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
         args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
   getArg = function(argName, defaultVal) {
      argName = argName.toLowerCase();
      return typeof args[argName] == "undefined" // argName in args
         ? defaultVal
         : args[argName];
   };
   return getArg(argName, defaultVal);
}
function getArgOrPref(name, type, defaultVal) {
   var argVal = getArg(name);
   return argVal === undefined
      ? saveOptions
         ? prefs.get(name, type, defaultVal)
         : defaultVal
      : argVal;
}
function Prefs(ns) {
   if(!ns)
      ns = WScript.ScriptBaseName;
   var oSet = AkelPad.ScriptSettings();
   var state  = 0;
   var READ   = 0x1; //POB_READ
   var SAVE   = 0x2; //POB_SAVE
   var CLEAR  = 0x4; //POB_CLEAR
   var DWORD  = 1;   //PO_DWORD
   var BINARY = 2;   //PO_BINARY
   var STRING = 3;   //PO_STRING
   function get(name, type, defaultVal) {
      if(!(state & READ)) {
         end();
         if(!oSet.Begin(ns, READ))
            return defaultVal;
         state = READ;
      }
      var val = oSet.Read(name, type || DWORD);
      if(val === undefined)
         val = defaultVal;
      //oSet.End();
      return val;
   }
   function set(name, val) {
      if(!(state & SAVE)) {
         end();
         if(!oSet.Begin(ns, SAVE))
            return false;
         state = SAVE;
      }
      var sets;
      if(arguments.length == 1)
         sets = name;
      else {
         sets = {};
         sets[name] = val;
      }
      var ok = true;
      for(var name in sets) {
         var val = sets[name];
         var type = typeof val == "number" || typeof val == "boolean" ? DWORD : STRING;
         if(!oSet.Write(name, type, val))
            ok = false;
      }
      //oSet.End();
      return ok;
   }
   function begin(flags) {
      end();
      var ok = oSet.Begin(ns, flags);
      if(ok)
         state = flags;
      return ok;
   }
   function end() {
      if(!state)
         return true;
      var ok = oSet.End();
      if(ok)
         state = 0;
      return ok;
   }
   this.READ   = READ;
   this.SAVE   = SAVE;
   this.CLEAR  = CLEAR;
   this.DWORD  = DWORD;
   this.BINARY = BINARY;
   this.STRING = STRING;
   this.get    = get;
   this.set    = set;
   this.begin  = begin;
   this.end    = end;
}
<download | mirror | development version>
Go to longest line below or above current.
Screenshots



Last edited by Infocatcher on Mon Mar 03, 2014 8:39 am; edited 23 times in total
Back to top
View user's profile Send private message
KDJ



Joined: 06 Mar 2010
Posts: 1263
Location: Poland

PostPosted: Sun Dec 19, 2010 5:38 pm    Post subject: Reply with quote

Sort in columns.

SortInColumns.js

Code:
// SortInColumns.js - ver. 2014-04-14 (x86/x64)
//
// Usage:
// Call("Scripts::Main", 1, "SortInColumns.js")
//
// To effect was clearly visible, you should use a fixed-width font.
//
// Shortcut keys in dialog box:
// Enter - Sort
// Esc   - Close
// Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption   = "Sortowanie w kolumnach";
  var sTxtSortRange = "Zakres sortowania";
  var sTxtFrom      = "Od";
  var sTxtTo        = "Do";
  var sTxtColumns   = "&Kolumny:";
  var sTxtLines     = "&Wiersze:";
  var sTxtSortKeys  = "Klucze sortowania - kolumny";
  var sTxtKey       = "Klucz";
  var sTxtDesc      = "Malejąco";
  var sTxtIgCase    = "Ignoruj wlk. liter";
  var sTxtString    = "String";
  var sTxtLocale    = "Alfabetycznie";
  var sTxtNum       = "Numerycznie";
  var sTxtAllKeys   = "Wszystkie klucze";
  var sTxtDescAll   = "&Malejąco";
  var sTxtIgCaseAll = "&Ignoruj wlk. liter";
  var sTxtStringAll = "&String";
  var sTxtLocaleAll = "&Alfabetycznie";
  var sTxtNumAll    = "&Numerycznie";
  var sTxtReverse   = "&Odwróć tylko kolejność wierszy";
  var sTxtCopyToCB  = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtSort      = "Sortuj";
  var sTxtUndo      = "&Cofnij";
  var sTxtRedo      = "&Powtórz";
  var sTxtNoRangeC  = "Brak zakresu kolumn do sortowania.";
  var sTxtNoRangeL  = "Brak zakresu wierszy do sortowania.";
  var sTxtNoKey1    = "Brak zakresu kolumn w pierwszym kluczu.";
}
else
{
  var sTxtCaption   = "Sort in columns";
  var sTxtSortRange = "Sort range";
  var sTxtFrom      = "From";
  var sTxtTo        = "To";
  var sTxtColumns   = "&Columns:";
  var sTxtLines     = "&Lines:";
  var sTxtSortKeys  = "Sort keys - columns";
  var sTxtKey       = "Key";
  var sTxtDesc      = "Descending";
  var sTxtIgCase    = "Ignore case";
  var sTxtString    = "String";
  var sTxtLocale    = "Alphabetically";
  var sTxtNum       = "Numerically";
  var sTxtAllKeys   = "All keys";
  var sTxtDescAll   = "&Descending";
  var sTxtIgCaseAll = "&Ignore case";
  var sTxtStringAll = "&String";
  var sTxtLocaleAll = "&Alphabetically";
  var sTxtNumAll    = "&Numerically";
  var sTxtReverse   = "Reverse &order of lines only";
  var sTxtCopyToCB  = "Resul&t copy to clipboard, do not replace text";
  var sTxtSort      = "Sort";
  var sTxtUndo      = "&Undo";
  var sTxtRedo      = "&Redo";
  var sTxtNoRangeC  = "There is no range of columns to sort.";
  var sTxtNoRangeL  = "There is no range of lines to sort.";
  var sTxtNoKey1    = "There is no range of columns in first sort key.";
}

var DT_DWORD    = 3;
var BM_GETCHECK = 240;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var aDesc      = [0,0,0,0,0];
var aIgCase    = [1,1,1,1,1];
var aString    = [1,1,1,1,1];
var aLocale    = [0,0,0,0,0];
var aNum       = [0,0,0,0,0];
var bDescAll   = 0;
var bIgCaseAll = 1;
var nMethod    = 1;
var bReverse   = 0;
var bCopyToCB  = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var nWordWrap;
var nLastLine;
var nLastCol;
var hWndDlg;
var lpBuffer;
var bGetSel;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd        = [];
var IDSORTRANGE = 1000;
var IDFROM      = 1001;
var IDTO        = 1002;
var IDCOLUMNS   = 1003;
var IDBEGCOL    = 1004;
var IDENDCOL    = 1005;
var IDLINES     = 1006;
var IDBEGLINE   = 1007;
var IDENDLINE   = 1008;
var IDSORTK1    = 1009;
var IDSORTK2    = 1010;
var IDSORTK3    = 1011;
var IDSORTK4    = 1012;
var IDSORTK5    = 1013;
var IDSORTK6    = 1014;
var IDFROM1     = 1015;
var IDTO1       = 1016;
var IDALLKEYS   = 1017;
var IDKEY1      = 1018;
var IDBEGCOL1   = 1019;
var IDENDCOL1   = 1020;
var IDDESC1     = 1021;
var IDIGCASE1   = 1022;
var IDSTRING1   = 1023;
var IDLOCALE1   = 1024;
var IDNUM1      = 1025;
var IDKEY2      = 1026;
var IDBEGCOL2   = 1027;
var IDENDCOL2   = 1028;
var IDDESC2     = 1029;
var IDIGCASE2   = 1030;
var IDSTRING2   = 1031;
var IDLOCALE2   = 1032;
var IDNUM2      = 1033;
var IDKEY3      = 1034;
var IDBEGCOL3   = 1035;
var IDENDCOL3   = 1036;
var IDDESC3     = 1037;
var IDIGCASE3   = 1038;
var IDSTRING3   = 1039;
var IDLOCALE3   = 1040;
var IDNUM3      = 1041;
var IDKEY4      = 1042;
var IDBEGCOL4   = 1043;
var IDENDCOL4   = 1044;
var IDDESC4     = 1045;
var IDIGCASE4   = 1046;
var IDSTRING4   = 1047;
var IDLOCALE4   = 1048;
var IDNUM4      = 1049;
var IDKEY5      = 1050;
var IDBEGCOL5   = 1051;
var IDENDCOL5   = 1052;
var IDDESC5     = 1053;
var IDIGCASE5   = 1054;
var IDSTRING5   = 1055;
var IDLOCALE5   = 1056;
var IDNUM5      = 1057;
var IDDESCALL   = 1058;
var IDIGCASEALL = 1059;
var IDSTRINGALL = 1060;
var IDLOCALEALL = 1061;
var IDNUMALL    = 1062;
var IDREVERSE   = 1063;
var IDCOPYTOCB  = 1064;
var IDSORT      = 1065;
var IDUNDO      = 1066;
var IDREDO      = 1067;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50012080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER
//Windows               CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDSORTRANGE] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 195,  85, sTxtSortRange];
aWnd[IDFROM     ] = ["STATIC",   0,       0, 0x50000000,  80,  25,  55,  13, sTxtFrom];
aWnd[IDTO       ] = ["STATIC",   0,       0, 0x50000000, 140,  25,  55,  13, sTxtTo];
aWnd[IDCOLUMNS  ] = ["STATIC",   0,       0, 0x50000000,  20,  40,  60,  13, sTxtColumns];
aWnd[IDBEGCOL   ] = ["EDIT",     0,   0x200, 0x50012080,  80,  40,  55,  20, ""];
aWnd[IDENDCOL   ] = ["EDIT",     0,   0x200, 0x50012080, 140,  40,  55,  20, ""];
aWnd[IDLINES    ] = ["STATIC",   0,       0, 0x50000000,  20,  65,  60,  13, sTxtLines];
aWnd[IDBEGLINE  ] = ["EDIT",     0,   0x200, 0x50012080,  80,  65,  55,  20, ""];
aWnd[IDENDLINE  ] = ["EDIT",     0,   0x200, 0x50012080, 140,  65,  55,  20, ""];
aWnd[IDSORTK1   ] = ["BUTTON",   0,       0, 0x50000007,  10, 110, 290,  82, sTxtSortKeys];
aWnd[IDSORTK2   ] = ["BUTTON",   0,       0, 0x50000007,  10, 185, 290,  82, ""];
aWnd[IDSORTK3   ] = ["BUTTON",   0,       0, 0x50000007,  10, 260, 290,  82, ""];
aWnd[IDSORTK4   ] = ["BUTTON",   0,       0, 0x50000007,  10, 335, 290,  82, ""];
aWnd[IDSORTK5   ] = ["BUTTON",   0,       0, 0x50000007,  10, 410, 290,  82, ""];
aWnd[IDSORTK6   ] = ["BUTTON",   0,       0, 0x50000007,  10, 485, 290,  82, ""];
aWnd[IDFROM1    ] = ["STATIC",   0,       0, 0x50000000,  80, 125,  55,  13, sTxtFrom];
aWnd[IDTO1      ] = ["STATIC",   0,       0, 0x50000000, 140, 125,  55,  13, sTxtTo];
aWnd[IDALLKEYS  ] = ["STATIC",   0,       0, 0x50000000,  20, 515,  90,  13, sTxtAllKeys];
aWnd[IDKEY1     ] = ["STATIC",   0,       0, 0x50000000,  20, 140,  60,  13, sTxtKey+" &1:"];
aWnd[IDBEGCOL1  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 140,  55,  20, ""];
aWnd[IDENDCOL1  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 140,  55,  20, ""];
aWnd[IDDESC1    ] = ["BUTTON",   0,       0, 0x50010003, 205, 125,  90,  16, sTxtDesc];
aWnd[IDIGCASE1  ] = ["BUTTON",   0,       0, 0x50010003, 205, 145,  90,  16, sTxtIgCase];
aWnd[IDSTRING1  ] = ["BUTTON",   0,       0, 0x50010003,  50, 170,  60,  16, sTxtString];
aWnd[IDLOCALE1  ] = ["BUTTON",   0,       0, 0x50010003, 110, 170,  90,  16, sTxtLocale];
aWnd[IDNUM1     ] = ["BUTTON",   0,       0, 0x50010003, 205, 170,  90,  16, sTxtNum];
aWnd[IDKEY2     ] = ["STATIC",   0,       0, 0x50000000,  20, 215,  60,  13, sTxtKey+" &2:"];
aWnd[IDBEGCOL2  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 215,  55,  20, ""];
aWnd[IDENDCOL2  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 215,  55,  20, ""];
aWnd[IDDESC2    ] = ["BUTTON",   0,       0, 0x50010003, 205, 200,  90,  16, sTxtDesc];
aWnd[IDIGCASE2  ] = ["BUTTON",   0,       0, 0x50010003, 205, 220,  90,  16, sTxtIgCase];
aWnd[IDSTRING2  ] = ["BUTTON",   0,       0, 0x50010003,  50, 245,  60,  16, sTxtString];
aWnd[IDLOCALE2  ] = ["BUTTON",   0,       0, 0x50010003, 110, 245,  90,  16, sTxtLocale];
aWnd[IDNUM2     ] = ["BUTTON",   0,       0, 0x50010003, 205, 245,  90,  16, sTxtNum];
aWnd[IDKEY3     ] = ["STATIC",   0,       0, 0x50000000,  20, 290,  60,  13, sTxtKey+" &3:"];
aWnd[IDBEGCOL3  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 290,  55,  20, ""];
aWnd[IDENDCOL3  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 290,  55,  20, ""];
aWnd[IDDESC3    ] = ["BUTTON",   0,       0, 0x50010003, 205, 275,  90,  16, sTxtDesc];
aWnd[IDIGCASE3  ] = ["BUTTON",   0,       0, 0x50010003, 205, 295,  90,  16, sTxtIgCase];
aWnd[IDSTRING3  ] = ["BUTTON",   0,       0, 0x50010003,  50, 320,  60,  16, sTxtString];
aWnd[IDLOCALE3  ] = ["BUTTON",   0,       0, 0x50010003, 110, 320,  90,  16, sTxtLocale];
aWnd[IDNUM3     ] = ["BUTTON",   0,       0, 0x50010003, 205, 320,  90,  16, sTxtNum];
aWnd[IDKEY4     ] = ["STATIC",   0,       0, 0x50000000,  20, 365,  60,  13, sTxtKey+" &4:"];
aWnd[IDBEGCOL4  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 365,  55,  20, ""];
aWnd[IDENDCOL4  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 365,  55,  20, ""];
aWnd[IDDESC4    ] = ["BUTTON",   0,       0, 0x50010003, 205, 350,  90,  16, sTxtDesc];
aWnd[IDIGCASE4  ] = ["BUTTON",   0,       0, 0x50010003, 205, 370,  90,  16, sTxtIgCase];
aWnd[IDSTRING4  ] = ["BUTTON",   0,       0, 0x50010003,  50, 395,  60,  16, sTxtString];
aWnd[IDLOCALE4  ] = ["BUTTON",   0,       0, 0x50010003, 110, 395,  90,  16, sTxtLocale];
aWnd[IDNUM4     ] = ["BUTTON",   0,       0, 0x50010003, 205, 395,  90,  16, sTxtNum];
aWnd[IDKEY5     ] = ["STATIC",   0,       0, 0x50000000,  20, 440,  60,  13, sTxtKey+" &5:"];
aWnd[IDBEGCOL5  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 440,  55,  20, ""];
aWnd[IDENDCOL5  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 440,  55,  20, ""];
aWnd[IDDESC5    ] = ["BUTTON",   0,       0, 0x50010003, 205, 425,  90,  16, sTxtDesc];
aWnd[IDIGCASE5  ] = ["BUTTON",   0,       0, 0x50010003, 205, 445,  90,  16, sTxtIgCase];
aWnd[IDSTRING5  ] = ["BUTTON",   0,       0, 0x50010003,  50, 470,  60,  16, sTxtString];
aWnd[IDLOCALE5  ] = ["BUTTON",   0,       0, 0x50010003, 110, 470,  90,  16, sTxtLocale];
aWnd[IDNUM5     ] = ["BUTTON",   0,       0, 0x50010003, 205, 470,  90,  16, sTxtNum];
aWnd[IDDESCALL  ] = ["BUTTON",   0,       0, 0x50010003, 205, 500,  90,  16, sTxtDescAll];
aWnd[IDIGCASEALL] = ["BUTTON",   0,       0, 0x50010003, 205, 520,  90,  16, sTxtIgCaseAll];
aWnd[IDSTRINGALL] = ["BUTTON",   0,       0, 0x50010003,  50, 545,  60,  16, sTxtStringAll];
aWnd[IDLOCALEALL] = ["BUTTON",   0,       0, 0x50010003, 110, 545,  90,  16, sTxtLocaleAll];
aWnd[IDNUMALL   ] = ["BUTTON",   0,       0, 0x50010003, 205, 545,  90,  16, sTxtNumAll];
aWnd[IDREVERSE  ] = ["BUTTON",   0,       0, 0x50010003,  20, 575, 170,  16, sTxtReverse];
aWnd[IDCOPYTOCB ] = ["BUTTON",   0,       0, 0x50010003,  20, 595, 270,  16, sTxtCopyToCB];
aWnd[IDSORT     ] = ["BUTTON",   0,       0, 0x50010000, 220,  15,  80,  23, sTxtSort];
aWnd[IDUNDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  47,  80,  23, sTxtUndo];
aWnd[IDREDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  72,  80,  23, sTxtRedo];

if (hEditWnd)
{
  nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

  if (! AkelPad.SendMessage(hEditWnd, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0))
    AkelPad.SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, 1 /*AESELT_COLUMNON*/, 0);

  nLastLine = AkelPad.SendMessage(hEditWnd, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
  nLastCol  = LineMaxLength() + 1;

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  315,             //nWidth
                  650,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }

  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    CheckButtonsAll(0);
    CheckUndoRedo();

    bGetSel = GetSelection();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);
  }

  else if (uMsg == 7) //WM_SETFOCUS
  {
    oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    AkelPad.SendMessage(aWnd[IDBEGCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
  }

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 9) //VK_TAB
      SetSelection();
    else if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam == IDBEGCOL)  || (nLowParam == IDENDCOL)  ||
        (nLowParam == IDBEGLINE) || (nLowParam == IDENDLINE) ||
        (nLowParam == IDBEGCOL1) || (nLowParam == IDENDCOL1) ||
        (nLowParam == IDBEGCOL2) || (nLowParam == IDENDCOL2) ||
        (nLowParam == IDBEGCOL3) || (nLowParam == IDENDCOL3) ||
        (nLowParam == IDBEGCOL4) || (nLowParam == IDENDCOL4) ||
        (nLowParam == IDBEGCOL5) || (nLowParam == IDENDCOL5))
    {
      CheckEditValue(nLowParam);
      if (bGetSel)
        SetSelection();
    }

    else if (((nLowParam >= IDDESC1) && (nLowParam <= IDNUM1)) ||
             ((nLowParam >= IDDESC2) && (nLowParam <= IDNUM2)) ||
             ((nLowParam >= IDDESC3) && (nLowParam <= IDNUM3)) ||
             ((nLowParam >= IDDESC4) && (nLowParam <= IDNUM4)) ||
             ((nLowParam >= IDDESC5) && (nLowParam <= IDNUM5)))
    {
      CheckButtons1(nLowParam);
      SetSelection();
    }

    else if ((nLowParam >= IDDESCALL) && (nLowParam <= IDCOPYTOCB))
    {
      CheckButtonsAll(nLowParam);
      SetSelection();
    }

    else if (nLowParam == IDSORT)
    {
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
      SetSelection();
      if (SortColumns())
      {
        SetSelection();
        CheckUndoRedo(nLowParam);
      }
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("User32::PostQuitMessage", 0);
  }

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(lpRect,     DT_DWORD);
  aRect.top    = AkelPad.MemRead(lpRect + 4, DT_DWORD);
  aRect.right  = AkelPad.MemRead(lpRect + 8, DT_DWORD);
  aRect.bottom = AkelPad.MemRead(lpRect +12, DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);

    sIniTxt = 'nWndPosX='   + aRect.left + ';\r\n' +
              'nWndPosY='   + aRect.top  + ';\r\n' +
              'aDesc=['     + aDesc + '];\r\n' +
              'aIgCase=['   + aIgCase + '];\r\n' +
              'aString=['   + aString + '];\r\n' +
              'aLocale=['   + aLocale + '];\r\n' +
              'aNum=['      + aNum + '];\r\n' +
              'bDescAll='   + bDescAll + ';\r\n' +
              'bIgCaseAll=' + bIgCaseAll + ';\r\n' +
              'nMethod='    + nMethod + ';\r\n' +
              'bReverse='   + bReverse + ';\r\n' +
              'bCopyToCB='  + bCopyToCB + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {
    }
  }
}

function CheckButtonsAll(nButton)
{
  var nDif = IDDESC2 - IDDESC1;
  var i;

  if (nButton == IDDESCALL)
  {
    bDescAll = AkelPad.SendMessage(aWnd[IDDESCALL][WND], BM_GETCHECK, 0, 0);
    aDesc    = [bDescAll, bDescAll, bDescAll, bDescAll, bDescAll];
  }
  else if (nButton == IDIGCASEALL)
  {
    bIgCaseAll = AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_GETCHECK, 0, 0);
    aIgCase    = [bIgCaseAll, bIgCaseAll, bIgCaseAll, bIgCaseAll, bIgCaseAll];
  }
  else if ((nButton == IDSTRINGALL) || (nButton == IDLOCALEALL) || (nButton == IDNUMALL))
  {
    if (nMethod == nButton - IDSTRINGALL + 1)
      nMethod = 0;
    else
    {
      nMethod = nButton - IDSTRINGALL + 1;
      aString = [0,0,0,0,0];
      aLocale = [0,0,0,0,0];
      aNum    = [0,0,0,0,0];
      if (nMethod == 1)
        aString = [1,1,1,1,1];
      else if (nMethod == 2)
        aLocale = [1,1,1,1,1];
      else if (nMethod == 3)
        aNum = [1,1,1,1,1];
    }
  }
  else if (nButton == IDREVERSE)
    bReverse = AkelPad.SendMessage(aWnd[IDREVERSE][WND],  BM_GETCHECK, 0, 0);
  else if (nButton == IDCOPYTOCB)
    bCopyToCB  = AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_GETCHECK, 0, 0);

  AkelPad.SendMessage(aWnd[IDDESCALL][WND],   BM_SETCHECK, bDescAll,       0);
  AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_SETCHECK, bIgCaseAll,     0);
  AkelPad.SendMessage(aWnd[IDSTRINGALL][WND], BM_SETCHECK, (nMethod == 1), 0);
  AkelPad.SendMessage(aWnd[IDLOCALEALL][WND], BM_SETCHECK, (nMethod == 2), 0);
  AkelPad.SendMessage(aWnd[IDNUMALL][WND],    BM_SETCHECK, (nMethod == 3), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],   BM_SETCHECK, bReverse,       0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_SETCHECK, bCopyToCB,      0);

  for (i = 0; i < 5; ++i)
  {
    AkelPad.SendMessage(aWnd[IDDESC1   + i * nDif][WND], BM_SETCHECK, aDesc[i],   0);
    AkelPad.SendMessage(aWnd[IDIGCASE1 + i * nDif][WND], BM_SETCHECK, aIgCase[i], 0);
    AkelPad.SendMessage(aWnd[IDSTRING1 + i * nDif][WND], BM_SETCHECK, aString[i], 0);
    AkelPad.SendMessage(aWnd[IDLOCALE1 + i * nDif][WND], BM_SETCHECK, aLocale[i], 0);
    AkelPad.SendMessage(aWnd[IDNUM1    + i * nDif][WND], BM_SETCHECK, aNum[i],    0);
  }

  for (i = IDSORTK1; i <= IDNUMALL; ++i)
    oSys.Call("User32::EnableWindow", aWnd[i][WND], ! bReverse);
}

function CheckButtons1(nButton)
{
  var nDif = IDDESC2 - IDDESC1;
  var nKey;
  var i;

  if (((nButton - IDDESC1) % nDif) == 0)
  {
    aDesc[(nButton - IDDESC1) / nDif] = AkelPad.SendMessage(aWnd[nButton][WND], BM_GETCHECK, 0, 0);
    if (aDesc[0] && aDesc[1] && aDesc[2] && aDesc[3] && aDesc[4])
      bDescAll = 1;
    else
      bDescAll = 0;
    AkelPad.SendMessage(aWnd[IDDESCALL][WND], BM_SETCHECK, bDescAll, 0);
  }
  else if (((nButton - IDIGCASE1) % nDif) == 0)
  {
    aIgCase[(nButton - IDIGCASE1) / nDif] = AkelPad.SendMessage(aWnd[nButton][WND], BM_GETCHECK, 0, 0);
    if (aIgCase[0] && aIgCase[1] && aIgCase[2] && aIgCase[3] && aIgCase[4])
      bIgCaseAll = 1;
    else
      bIgCaseAll = 0;
    AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_SETCHECK, bIgCaseAll, 0);
  }
  else
  {
    nKey = Math.floor((nButton - IDDESC1) / nDif);
    aString[nKey] = 0;
    aLocale[nKey] = 0;
    aNum[nKey]    = 0;

    if (((nButton - IDSTRING1) % nDif) == 0)
      aString[nKey] = 1;
    else if (((nButton - IDLOCALE1) % nDif) == 0)
      aLocale[nKey] = 1;
    else if (((nButton - IDNUM1) % nDif) == 0)
      aNum[nKey] = 1;

    AkelPad.SendMessage(aWnd[IDSTRING1 + nKey * nDif][WND], BM_SETCHECK, aString[nKey], 0);
    AkelPad.SendMessage(aWnd[IDLOCALE1 + nKey * nDif][WND], BM_SETCHECK, aLocale[nKey], 0);
    AkelPad.SendMessage(aWnd[IDNUM1    + nKey * nDif][WND], BM_SETCHECK, aNum[nKey],    0);

    if (aString[0] && aString[1] && aString[2] && aString[3] && aString[4])
      nMethod = 1;
    else if (aLocale[0] && aLocale[1] && aLocale[2] && aLocale[3] && aLocale[4])
      nMethod = 2;
    else if (aNum[0] && aNum[1] && aNum[2] && aNum[3] && aNum[4])
      nMethod = 3;
    else
      nMethod = 0;

    AkelPad.SendMessage(aWnd[IDSTRINGALL][WND], BM_SETCHECK, (nMethod == 1), 0);
    AkelPad.SendMessage(aWnd[IDLOCALEALL][WND], BM_SETCHECK, (nMethod == 2), 0);
    AkelPad.SendMessage(aWnd[IDNUMALL][WND],    BM_SETCHECK, (nMethod == 3), 0);
  }
}

function CheckUndoRedo(nButton)
{
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function CheckEditValue(nIdWnd)
{
  var sEditValue;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[nIdWnd][WND], lpBuffer, 256);
  sEditValue = AkelPad.MemRead(lpBuffer, _TSTR);

  if ((nIdWnd == IDBEGLINE) || (nIdWnd == IDENDLINE))
  {
    if (sEditValue == 0)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "1");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastLine)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastLine));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }

  else if ((nIdWnd == IDBEGCOL)  || (nIdWnd == IDENDCOL) ||
           (nIdWnd == IDBEGCOL1) || (nIdWnd == IDENDCOL1))
  {
    if (sEditValue == 0)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "1");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastCol)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastCol));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }

  else if ((nIdWnd == IDBEGCOL2) || (nIdWnd == IDENDCOL2) ||
           (nIdWnd == IDBEGCOL3) || (nIdWnd == IDENDCOL3) ||
           (nIdWnd == IDBEGCOL4) || (nIdWnd == IDENDCOL4) ||
           (nIdWnd == IDBEGCOL5) || (nIdWnd == IDENDCOL5))
  {
    if (sEditValue == "0")
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastCol)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastCol));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }
}

function GetSelection()
{
  var lpBegSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpEndSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var nLine1, nLine2, nCol1, nCol2;

  AkelPad.SendMessage(hEditWnd, 3123 /*AEM_EXGETSEL*/, lpBegSel, lpEndSel);

  nLine1 = AkelPad.MemRead(lpBegSel, DT_DWORD) + 1;
  nLine2 = AkelPad.MemRead(lpEndSel, DT_DWORD) + 1;

  if (AkelPad.MemRead(lpBegSel + (_X64 ? 16 : 8), DT_DWORD) < AkelPad.MemRead(lpEndSel + (_X64 ? 16 : 8), DT_DWORD))
  {
    nCol1 = AkelPad.MemRead(lpBegSel + (_X64 ? 16 : 8), DT_DWORD) + 1;
    nCol2 = AkelPad.MemRead(lpEndSel + (_X64 ? 16 : 8), DT_DWORD) + 1;
  }
  else
  {
    nCol1 = AkelPad.MemRead(lpEndSel + (_X64 ? 16 : 8), DT_DWORD) + 1;
    nCol2 = AkelPad.MemRead(lpBegSel + (_X64 ? 16 : 8), DT_DWORD) + 1;
  }

  SetWindowFontAndText(aWnd[IDBEGLINE][WND], hGuiFont, String(nLine1));
  SetWindowFontAndText(aWnd[IDENDLINE][WND], hGuiFont, String(nLine2));
  SetWindowFontAndText(aWnd[IDBEGCOL][WND],  hGuiFont, String(nCol1));
  SetWindowFontAndText(aWnd[IDENDCOL][WND],  hGuiFont, String(nCol2));
  SetWindowFontAndText(aWnd[IDBEGCOL1][WND], hGuiFont, String(nCol1));
  SetWindowFontAndText(aWnd[IDENDCOL1][WND], hGuiFont, String(nCol2));

  AkelPad.MemFree(lpBegSel);
  AkelPad.MemFree(lpEndSel);
  return 1;
}

function SetSelection()
{
  var hWndFocus = oSys.Call("User32::GetFocus");
  var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpBegSel  = lpSelect;
  var lpEndSel  = lpSelect + (_X64 ? 24 : 12);
  var lpSelFlag = lpSelect + (_X64 ? 48 : 24);
  var nLine1, nLine2, nCol1, nCol2, i;

  for (i = 1000; i < aWnd.length; ++i)
  {
    if (aWnd[i][WND] == hWndFocus)
      break;
  }

  if ((i >= IDBEGCOL1) && (i <= IDNUM1))
    i = IDBEGCOL1;
  else if ((i >= IDBEGCOL2) && (i <= IDNUM2))
    i = IDBEGCOL2;
  else if ((i >= IDBEGCOL3) && (i <= IDNUM3))
    i = IDBEGCOL3;
  else if ((i >= IDBEGCOL4) && (i <= IDNUM4))
    i = IDBEGCOL4;
  else if ((i >= IDBEGCOL5) && (i <= IDNUM5))
    i = IDBEGCOL5;
  else
    i = IDBEGCOL;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[i][WND], lpBuffer, 256);
  nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[i + 1][WND], lpBuffer, 256);
  nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if ((nCol1 < 0) || (nCol2 < 0))
    nCol1 = nCol2 = 0;

  AkelPad.MemCopy(lpBegSel, nLine1, DT_DWORD);
  AkelPad.MemCopy(lpBegSel + (_X64 ? 16 : 8), nCol1, DT_DWORD);
  AkelPad.MemCopy(lpEndSel, nLine2, DT_DWORD);
  AkelPad.MemCopy(lpEndSel + (_X64 ? 16 : 8), nCol2, DT_DWORD);
  AkelPad.MemCopy(lpSelFlag, 1, DT_DWORD);

  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpBegSel);
  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpEndSel);

  AkelPad.SendMessage(hEditWnd, 3126 /*AEM_SETSEL*/, 0, lpSelect);

  AkelPad.MemFree(lpSelect);
}

function LineMaxLength()
{
  var nMaxLenL = 0;
  var nBegLine;
  var nLenLine;
  var i;

  for (i = 0; i < nLastLine; ++i)
  {
    nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
    nLenLine = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
    if (nLenLine > nMaxLenL)
      nMaxLenL = nLenLine;
  }

  return nMaxLenL;
}

function SortColumns()
{
  var aDesc   = new Array(5);
  var aIgCase = new Array(5);
  var aString = new Array(5);
  var aLocale = new Array(5);
  var aNum    = new Array(5);
  var aCol    = [[], [], [], [], [], []];
  var aTxt    = [];
  var sText   = "";
  var nDif    = IDBEGCOL2 - IDBEGCOL1;
  var nLine1;
  var nLine2;
  var i;

  for (i = 0; i < 5; ++i)
  {
    aDesc[i]   = AkelPad.SendMessage(aWnd[IDDESC1   + i * nDif][WND], BM_GETCHECK, 0, 0);
    aIgCase[i] = AkelPad.SendMessage(aWnd[IDIGCASE1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aString[i] = AkelPad.SendMessage(aWnd[IDSTRING1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aLocale[i] = AkelPad.SendMessage(aWnd[IDLOCALE1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aNum[i]    = AkelPad.SendMessage(aWnd[IDNUM1    + i * nDif][WND], BM_GETCHECK, 0, 0);
  }

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
  aCol[0][0] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
  aCol[0][1] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  for (i = 1; i < 6; ++i)
  {
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL1 + (i - 1) * nDif][WND], lpBuffer, 256);
    aCol[i][0] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL1 + (i - 1) * nDif][WND], lpBuffer, 256);
    aCol[i][1] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
    if ((aCol[i][0] == 0) || (aCol[i][1] == 0) || (aCol[i][0] == aCol[i][1]))
    {
      aCol[i][0] = aCol[i][1] = 0;
      SetWindowFontAndText(aWnd[IDBEGCOL1 + (i - 1) * nDif][WND], hGuiFont, String(aCol[i][0]));
      SetWindowFontAndText(aWnd[IDENDCOL1 + (i - 1) * nDif][WND], hGuiFont, String(aCol[i][1]));
    }
  }

  if (aCol[0][0] == aCol[0][1])
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeC, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  if (nLine1 == nLine2)
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeL, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDLINE][WND]);
    AkelPad.SendMessage(aWnd[IDENDLINE][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  if ((aCol[1][0] == aCol[1][1]) && (! bReverse))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoKey1, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL1][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL1][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  for (i = 5; i >= 0; --i)
  {
    if (aCol[i][0] == 0)
    {
      aCol.splice(i, 1);
      aDesc.splice(i - 1, 1);
      aIgCase.splice(i - 1, 1);
      aString.splice(i - 1, 1);
      aLocale.splice(i - 1, 1);
      aNum.splice(i - 1, 1);
    }
    else
    {
      --aCol[i][0];
      --aCol[i][1];
    }
  }
  --nLine1;
  --nLine2;

  if (bReverse)
  {
    aTxt  = GetTextRangeColumn([nLine1, aCol[0][0]], [nLine2, aCol[0][1]]);
    sText = aTxt.reverse().join("\r");
  }
  else
  {
    aTxt.length = aCol.length;
    for (i = 0; i < aTxt.length; ++i)
      aTxt[i] = GetTextRangeColumn([nLine1, aCol[i][0]], [nLine2, aCol[i][1]]);

    aTxt = ArrayTransp(aTxt);

    ArraySort(aTxt, aDesc, aIgCase, aString, aLocale, aNum);

    for (i = 0; i < aTxt.length; ++i)
    {
      sText += aTxt[i][0] + "\r";
    }
    sText = sText.slice(0, -1);
  }

  AkelPad.SendMessage(aWnd[IDBEGCOL][WND], 177 /*EM_SETSEL*/, 0, -1);

  if (bCopyToCB)
  {
    AkelPad.SetClipboardText(sText);
    return 0;
  }
  else
  {
    AkelPad.ReplaceSel(sText);
    return 1;
  }
}

function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

   nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
   nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
   nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}

function ArrayTransp(aArr)
{
  var nLen1 = aArr.length;
  var nLen2 = aArr[0].length;
  var aArr2 = [];
  var i, n;

  aArr2.length = nLen2;

  for (n = 0; n < nLen2; ++n)
  {
    aArr2[n] = [];
    for (i = 0; i < nLen1; ++i)
    {
      aArr2[n].push(aArr[i][n]);
    }
  }
  return aArr2;
}

function ArraySort(aTxt, aDesc, aIgCase, aString, aLocale, aNum)
{
  var lpStrA = AkelPad.MemAlloc(nLastCol * _TSIZE);
  var lpStrB = AkelPad.MemAlloc(nLastCol * _TSIZE);
  var nComp;
  var i;

  aTxt.sort(function(a, b) {
    for (i = 0; i < aDesc.length; ++i)
    {
      nComp = CompareValue(a[i + 1], b[i + 1], lpStrA, lpStrB, aDesc[i], aIgCase[i], aString[i], aLocale[i], aNum[i]);
      if (nComp != 0)
        return nComp;
    }
    return 0; });

  AkelPad.MemFree(lpStrA);
  AkelPad.MemFree(lpStrB);
}

function CompareValue(ValA, ValB, lpStrA, lpStrB, bDesc, bIgCase, bString, bLocale, bNum)
{
  var nResult;

  if (bString)
  {
    if (bIgCase)
    {
      ValA = ValA.toUpperCase();
      ValB = ValB.toUpperCase();
    }
    if (ValA > ValB)
      nResult = bDesc ? -1 : 1;
    else if (ValA < ValB)
      nResult = bDesc ? 1 : -1;
    else
      nResult = 0;
  }
  else if (bLocale)
  {
    AkelPad.MemCopy(lpStrA, ValA, _TSTR);
    AkelPad.MemCopy(lpStrB, ValB, _TSTR);
    nResult = oSys.Call("Kernel32::lstrcmp" + (bIgCase ? "i" : "") + _TCHAR, lpStrA, lpStrB);
    if (bDesc)
      nResult = -nResult;
  }
  else
  {
    var oRegExp = /(-?\d+\.?\d*)|(-?\.\d+)/;

    ValA    = oRegExp.exec(ValA);
    ValB    = oRegExp.exec(ValB);
    ValA    = ValA ? parseFloat(ValA[0]) : 0;
    ValB    = ValB ? parseFloat(ValB[0]) : 0;
    nResult = bDesc ? (ValB - ValA) : (ValA - ValB);
  }

  return nResult;
}


Last edited by KDJ on Mon Apr 14, 2014 8:17 pm; edited 13 times in total
Back to top
View user's profile Send private message
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Wed Dec 29, 2010 4:45 pm    Post subject: Reply with quote

TabsToSpaces_mod.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7081#7081

/// Convert tabulation to space for AkelPad 4.x.x

// Modified by Infocatcher
// version: 2010-12-29

var hMainWnd=AkelPad.GetMainWnd();
var hWndEdit=AkelPad.GetEditWnd();
var oSys=AkelPad.SystemFunction();
var pScriptName=WScript.ScriptName;
var pSelText;
var pResult;
var pSpaces;
var nSelStart;
var nSelEnd;
var nTabStop;
var nColumn;
var nSpaceCount;
var a;
var b;

if (hMainWnd)
{
  if (AkelPad.IsAkelEdit())
  {
    nSelStart=AkelPad.GetSelStart();
    nSelEnd=AkelPad.GetSelEnd();
    if (nSelStart == nSelEnd)
    {
      //AkelPad.SetSel(0, -1);
      nSelStart = 0;
      nSelEnd = -1;
      pSelText = AkelPad.GetTextRange(0, -1);
    }
    else
    {
      //SelCompleteLine(hWndEdit, nSelStart, nSelEnd);
      var sel = GetCompleteLine(hWndEdit, nSelStart, nSelEnd);
      nSelStart = sel[0];
      nSelEnd   = sel[1];
      pSelText = AkelPad.GetTextRange(nSelStart, nSelEnd);
    }
    //nSelStart=AkelPad.GetSelStart();
    //nSelEnd=AkelPad.GetSelEnd();
    //pSelText=AkelPad.GetSelText();

    nTabStop=AkelPad.SendMessage(hWndEdit, 3239 /*AEM_GETTABSTOP*/, 0, 0);
    pResult="";

    if (pSelText.indexOf("\t") == -1)
    {
      pResult = pSelText.replace(
        new RegExp("^( {" + nTabStop + "})+", "mg"),
        function(s)
        {
          return new Array(s.length/nTabStop + 1).join("\t");
        }
      );
    }
    else
    {
      for (a=0, b=0, nColumn=0; b < pSelText.length; ++b)
      {
        if (pSelText.charAt(b) == '\t')
        {
          nSpaceCount=nTabStop - nColumn % nTabStop;
          nColumn+=nSpaceCount;
          for (pSpaces=""; nSpaceCount; --nSpaceCount)
            pSpaces=pSpaces + " ";
          pResult=pResult + pSelText.substr(a, b - a) + pSpaces;
          a=b + 1;
        }
        else if (pSelText.charAt(b) == '\r')
          nColumn=0;
        else
          ++nColumn;
      }
      pResult=pResult + pSelText.substr(a, b - a);
   }

    //AkelPad.ReplaceSel(pResult);
    insertNoScroll(pResult, nSelStart, nSelEnd);
  }
}


//Functions
function GetCompleteLine(hWnd, nMinSel, nMaxSel)
{
  var nMinLine;
  var nMaxLine;
  var nMinLineIndex;
  var nMaxLineIndex;
  var nMaxLineLength;

  if (nMinSel < nMaxSel)
  {
    nMinLine=AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMinSel);
    nMaxLine=AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMaxSel);
    nMinLineIndex=AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nMinLine, 0);
    nMaxLineIndex=AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nMaxLine, 0);
    nMaxLineLength=AkelPad.SendMessage(hWnd, 193 /*EM_LINELENGTH*/, nMaxSel, 0);

    if (nMaxLineIndex == nMaxSel) --nMaxLine;
    else if (nMaxLineLength) nMaxSel=nMaxLineIndex + nMaxLineLength + 1;
    nMinSel=nMinLineIndex;

    //AkelPad.SetSel(nMinSel, nMaxSel);
    //return nMaxLine - nMinLine + 1;
    return [nMinSel, nMaxSel];
  }
  //return 0;
  throw new Error("GetCompleteLine: nMinSel >= nMaxSel");
}
function insertNoScroll(str, nSelStart, nSelEnd) {
   var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
   if(!lpPoint)
      return;
   //var hWndEdit = AkelPad.GetEditWnd();
   setRedraw(hWndEdit, false);
   AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

   AkelPad.SetSel(nSelStart, nSelEnd);
   //var ss = AkelPad.GetSelStart();
   AkelPad.ReplaceSel(str, true);
   //if(ss != AkelPad.GetSelStart())
   //   AkelPad.SetSel(ss, ss + str.length);

   AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
   setRedraw(hWndEdit, true);
   AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Modified version of TabsToSpaces.js.
Added text inserting without scroll and backward replacement, if text doesn't contain tabulations.


Last edited by Infocatcher on Fri May 11, 2012 6:06 pm; edited 1 time in total
Back to top
View user's profile Send private message
FeyFre



Joined: 07 Aug 2007
Posts: 2007
Location: Vinnitsa, Ukraine

PostPosted: Thu Dec 30, 2010 10:40 pm    Post subject: Reply with quote

Make AkelPad semitransparent
transparency.js
Code:
//! === [transparency.js] ===
//!   FeyFre (c) 2010
//!
//!   Sets transparency level of Akelpad main window(for Windows 2000/XP and newer)
//!   Arguments:
//!      * integer transparency level to set in range 0 till 255
//!      * "m" or "M" to set minimal and maximal alpha value
//!      * +value -value to change current transparency level
//!
//! Example:
//!      Fully visible
//!         Call("Scripts::Main", 1, "transparency.js", "m")
//!      Fully transparent(do not recommended to use unless you have assigned hotkey to reset transparency level)
//!         Call("Scripts::Main", 1, "transparency.js", "M")
//!      Semitransparent:
//!         Call("Scripts::Main", 1, "transparency.js", "127")
//!      Increase transparency
//!         Call("Scripts::Main", 1, "transparency.js", "+33")
//!      Decrease transparency
//!         Call("Scripts::Main", 1, "transparency.js", "-33")
//!
var ACTION_NONE = -1;
var ACTION_SET = 0
var ACTION_INC = 1;
//! Defaults
var action = ACTION_SET;
var data = 127;
var oSys = AkelPad.SystemFunction();
//! Parameters
if(WScript.Arguments.length > 0)
{
   var arg = WScript.Arguments(0);
   if(arg=='m')
   {
      action = ACTION_SET;
      data = 0;
   }
   else if(arg=='M')
   {
      action = ACTION_SET;
      data = 255;
   }
   else
   {
      action = ACTION_NONE;
      if(Number(arg) != NaN)
      {
         var ch = arg.charAt(0);
         data = Number(arg);
         if(ch =='+' || ch == '-')
         {
            action = ACTION_INC;
            //data = - data;
         }
         else
         {
            action = ACTION_SET;
         }
      }
   }
}

if(action != ACTION_NONE)
{
   var akel = AkelPad.GetMainWnd();
   //! We should add WS_EX_LAYERED extended style for windows in order to enable transparency
   var styleex = oSys.Call("user32::GetWindowLong"+_TCHAR,akel,-20/*GWL_EXSTYLE*/);
   styleex |= 0x00080000/*WS_EX_LAYERED*/;
   oSys.Call("user32::SetWindowLong"+_TCHAR,akel,-20/*GWL_EXSTYLE*/,styleex);
   do
   {
      if(action == ACTION_INC)
      {
         var mem = AkelPad.MemAlloc(1);
         var memfl = AkelPad.MemAlloc(4);
         AkelPad.MemCopy(memfl, 2, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(mem, 0, 5 /*DT_BYTE*/);
         //! Get current transparency level if any
         if(oSys.Call("user32::GetLayeredWindowAttributes",akel,0,mem,memfl))
         {
            var fl = AkelPad.MemRead(memfl, 3 /*DT_DWORD*/);
            if(fl & 2)
            {
               //! Do increase
               data = 255-AkelPad.MemRead(mem, 5 /*DT_BYTE*/) + data;
            }
            else data = 0;
         }
         AkelPad.MemFree(memfl);
         AkelPad.MemFree(mem);
      }
      //! Range checks
      if(data < 0) data = 0;
      if(data > 255) data = 255
      //! Set transparency
      oSys.Call("user32::SetLayeredWindowAttributes",akel,0,255-data,2/*LWA_ALPHA*/);
   }
   while(0);
   //! Force to redraw window, since we have changed extended style
   oSys.Call("user32::SetWindowPos",akel,0,0,0,0,0,55/*SWP_NOSIZE|SWP_NOMOVE|SWP_ZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED*/);
}
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
FeyFre



Joined: 07 Aug 2007
Posts: 2007
Location: Vinnitsa, Ukraine

PostPosted: Mon Jan 03, 2011 9:24 pm    Post subject: Reply with quote

Set Coder's syntax theme by extension Download
(!! REQUIRED: WIN32 Constant library !!)
Script also demonstrates concept of creating AkelPad dockbars(like QSearch, HexSel, Explorer etc) and typical usage of AkelPad.ScriptNoMutex()
SetCoderExt.js
Code:
// === Set Coder Extension theme ===
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10672#10672
// FeyFre (c) 2011-2014
//
//   v1.0.1 (2014.04.19) New Scripts plugin compatibility
//   Popups a dockbar which allows choose extension to activate for coder plugin.
//   Script should be positioned as a proof of concept for dockbar creation from scripts.
//   I have had no idea about existence of Highlighter.js when started to develop this script.
//   !!!Not tested on X64!!!
//
// Example:
//   Call("Scripts::Main", 1, "SetCoderExt.js")
//
//// REQUIRED: WIN32 Constant library at http://akelpad.sourceforge.net/forum/viewtopic.php?p=9420#9420

//! Окно редактора
var g_hAkelPad = AkelPad.GetMainWnd();
//! Прокси системных вызовов
var oSys=AkelPad.SystemFunction();
//! Модуль плагина
var g_hModuleDll = AkelPad.GetInstanceDll();
//! Флаг завершения обработы скрипта
var QuitMutext = false;
//! Shell
var WshShell=new ActiveXObject("WScript.shell");
//! Константы используемые системными вызовами
AkelPad.Include("win32\\user32.js");

//! Панелька
var g_pDock = 0;
//! Окно панельки
var g_hDockWnd = 0;
//! Класс окна панельки
var DOCKCLASSNAME = "WNDCLS_"+WScript.ScriptBaseName;
//! Элементы управления на панельке
var combo_ext   = 0;
var btn_set      = 0;
var btn_exit   = 0;
//! Идентификаторы элементов управления на панельке
var IDC_EXT      = 1000;
var IDC_SET      = 1001;
var IDC_EXIT   = 1002;

//! Взято из AkelDLL.h
var DKS_LEFT   =1
var DKS_RIGHT   =2
var DKS_TOP      =3
var DKS_BOTTOM   =4

//Dock flags
var DKF_OWNTHREAD      =0x00000001
var DKF_FIXEDSIZE      =0x00000002
var DKF_DRAGDROP      =0x00000004
var DKF_HIDDEN         =0x00000008
var DKF_NODROPLEFT      =0x00000010
var DKF_NODROPRIGHT      =0x00000020
var DKF_NODROPTOP      =0x00000040
var DKF_NODROPBOTTOM   =0x00000080

//Dock action
var DK_ADD         =0x00000001
var DK_DELETE      =0x00000002
var DK_SUBCLASS      =0x00000004
var DK_UNSUBCLASS   =0x00000008
var DK_SETLEFT      =0x00000010
var DK_SETRIGHT      =0x00000020
var DK_SETTOP      =0x00000040
var DK_SETBOTTOM   =0x00000080
var DK_HIDE         =0x00000100
var DK_SHOW         =0x00000200
var DK_FINDDOCK      =0x00000400
var DK_FINDCHILD   =0x00000800

var BIF_BITMAP      =0x001; //Bitmap handle is used in BUTTONDRAW.hImage.
var BIF_ICON      =0x002; //Icon handle is used in BUTTONDRAW.hImage.
var BIF_CROSS      =0x004; //Draw small cross 8x7. BUTTONDRAW.hImage is ignored.
var BIF_DOWNARROW   =0x008; //Draw small down arrow 7x4. BUTTONDRAW.hImage is ignored.
var BIF_ETCHED      =0x100; //Draw edge around button.
var BIF_ENABLEFOCUS   =0x200; //Draw focus rectangle when button receive focus.

var AKD_RESIZE         = WM_USER + 253;
var AKD_DOCK         = WM_USER + 254;
var AKD_SETBUTTONDRAW   = WM_USER + 255;
var AKDN_MAIN_ONFINISH   = WM_USER + 6;

var WSC_MAINPROC      = 1;
var WSC_EDITPROC      = 2;
var WSC_FRAMEPROC      = 3;

var ControlH = 25;
var ComboW = 130;
//// РАБОЧИЕ ФУНКЦИИ
//! Создаёт панельку
function CreateDock()
{
   var pDock = AkelPad.MemAlloc(52/*sizeof(DOCK)*/);
   var dockside = DKS_BOTTOM;
   try
   {
      dockside = WshShell.RegRead("HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\SetCoderExt\\Side");
   }catch(e){}
   switch(dockside)
   {
      case DKS_BOTTOM:case DKS_TOP:break;
      default:dockside = DKS_BOTTOM;
   }
   AkelPad.MemCopy(pDock + 8, DKF_OWNTHREAD|DKF_NODROPLEFT|DKF_NODROPRIGHT|DKF_FIXEDSIZE|DKF_DRAGDROP, 3 /*DT_DWORD*/);
   AkelPad.MemCopy(pDock + 16, dockside, 3 /*DT_DWORD*/);
   g_pDock = AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_ADD, pDock);
   AkelPad.MemFree(pDock);
   if(g_pDock != 0)
   {
      
      g_hDockWnd = CreateWindowEx(0,DOCKCLASSNAME,DOCKCLASSNAME,WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,400,ControlH + 4,g_hAkelPad,0,DockWindowProc);
      if(g_hDockWnd!=0)
      {
         GetWindowRect(g_hDockWnd,g_pDock+20);
         var szL = AkelPad.MemRead(g_pDock+20, 3 /*DT_DWORD*/);
         var szT = AkelPad.MemRead(g_pDock+24, 3 /*DT_DWORD*/);
         var szR = AkelPad.MemRead(g_pDock+28, 3 /*DT_DWORD*/);
         var szB = AkelPad.MemRead(g_pDock+32, 3 /*DT_DWORD*/);
         /*rcSize={0,0,right-left,bottom-top}*/
         AkelPad.MemCopy(g_pDock+20, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+24, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+28, szR-szL, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+32, szB-szT, 3 /*DT_DWORD*/);
         /*rcDragDrop=rcSize*/
         AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+12, g_hDockWnd, 3 /*DT_DWORD*/);
         AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SUBCLASS, g_pDock);
         AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
         return 1;
      }
      else
      {
         AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
         g_pDock = 0;
         return 0;
      }
   }
   else return 0;
}
//! Хук главного окна.
function AkelPadCallBack(hwnd,umsg,wparam,lparam)
{
   //! Нотификция о закрытии редактора
   if(umsg == AKDN_MAIN_ONFINISH)
   {
      AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
      while(!QuitMutext)
      {
         oSys.Call("kernel32::SwitchToThread");
      }
   }
   return 0;
}
//! Хук окна редактирования. Для перехвата Enter и Esc
function ComboSubClass(hwnd,umsg,wparam,lparam)
{
   if(umsg == WM_KEYDOWN)
   {
      var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
      if(! mod)
      {
         if(wparam == VK_RETURN)
         {
            AkelPad.SendMessage(g_hDockWnd, WM_COMMAND, (BN_CLICKED <<16)+IDC_SET, 0);
         }
         else if(wparam == VK_ESCAPE)
         {
            AkelPad.SendMessage(g_hDockWnd, WM_COMMAND, (BN_CLICKED <<16)+IDC_EXIT, 0);
         }
      }
   }
   else if (umsg == WM_GETDLGCODE)
   {
      return DLGC_WANTALLKEYS;
   }
}
//! Заполнить список доступных расширений
function FillCombo(hwnd, curext)
{
   //! Extension supported by Coder collected here(ini-format file)
   var txtExt = AkelPad.ReadFile(AkelPad.GetAkelDir()+"\\AkelFiles\\Plugs\\Coder\\cache");
   var lines = txtExt.split("\r\n");
   var inSection = false, l = 0;
   var cat=[];
   if(lines.length==0) return;
   for(l = 1; l<lines.length;l++)
   {
      var line = lines[l];
      var parts=line.split('=');
      if(parts.length>=2)
      {
         var exts=parts[1].split(" ");
         var each = null
         for(each in exts)
         {
            exts[each] = exts[each].replace('"','').replace('"','');
         }
         cat[parts[0]] = exts;
      }
   }
   var catname = "";
   for(catname in cat)
   {
      var catlabel = '==' + catname.toUpperCase() + '==';
      var cats = cat[catname];
      var mem = AkelPad.MemAlloc((catlabel.length+1)*_TSIZE);
      AkelPad.MemCopy(mem, catlabel, _TSTR);
      var index = AkelPad.SendMessage(hwnd, CB_ADDSTRING, 0, mem);
      if(index != -1)
      {
         AkelPad.SendMessage(hwnd, CB_SETITEMDATA, index, 0);
      }
      AkelPad.MemFree(mem);
      var exti=0;
      for(exti in cats)
      {
         var ext = cats[exti];
         mem = AkelPad.MemAlloc((ext.length+1)*_TSIZE);
         AkelPad.MemCopy(mem, ext, _TSTR);
         index = AkelPad.SendMessage(hwnd, CB_ADDSTRING, 0, mem);
         if(index != -1)
         {
            AkelPad.SendMessage(hwnd, CB_SETITEMDATA, index, 1);
         }
         AkelPad.MemFree(mem);
         if(curext == ext)
         {
            AkelPad.SendMessage(hwnd, CB_SETCURSEL, index, 0);
         }
      }
   }
}
//! Оконная процедура панельки
function DockWindowProc(hwnd, umsg, wparam,lparam)
{
   if(umsg == WM_CREATE)
   {
      var fname = AkelPad.GetEditFile(0);
      if(fname != "")
      {
         fname = fname.split('\\');
         fname = fname[fname.length-1];
         fname = fname.split('.');
         fname = fname[fname.length-1];
      }
      //! Создаем элементы управления
      combo_ext = CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","",
                     WS_CHILD|WS_VISIBLE|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|
                     CBS_DROPDOWNLIST|CBS_AUTOHSCROLL,
                     10,2,ComboW,ControlH,hwnd,IDC_EXT,0);
      FillCombo(combo_ext, fname);
      btn_set = CreateWindowEx(0,"BUTTON","SET",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,145,2,50,ControlH,hwnd,IDC_SET,0);
      btn_exit = CreateWindowEx(0,"BUTTON","EXIT",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|BS_OWNERDRAW,200,2,25,ControlH,hwnd,IDC_EXIT,0);
      //! Отображаем их
      ShowWindow(btn_set,SW_SHOW);UpdateWindow(btn_set);
      ShowWindow(btn_exit,SW_SHOW);UpdateWindow(btn_exit);
      ShowWindow(combo_ext,SW_SHOW);UpdateWindow(combo_ext);
      //! Рисовать кнопку закрытия
      var memBD = AkelPad.MemAlloc(16/*sizeof BUTTONDRAW*/);
      AkelPad.MemCopy(memBD+0, BIF_CROSS|BIF_ETCHED, 3 /*DT_DWORD*/);
      AkelPad.SendMessage(g_hAkelPad, AKD_SETBUTTONDRAW, btn_exit, memBD);
      AkelPad.MemFree(memBD);
      //! Фокус на строку ввода
      SetFocus(combo_ext);
      //! Сабкласим её, нужен перехват клавиш Escape и Enter
      AkelPad.WindowSubClass(combo_ext, ComboSubClass, WM_KEYDOWN, WM_GETDLGCODE);
      return 0;
   }
   else if(umsg == WM_KEYDOWN)
   {
      //! Перехват клавиш Escape и Enter на окне
      var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
      if(! mod)
      {
         if(wparam == VK_RETURN)
         {
            AkelPad.SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_SET,BN_CLICKED), 0);
         }
         else if(wparam == VK_ESCAPE)
         {
            AkelPad.SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_EXIT,BN_CLICKED), 0);
         }
      }
   }
   else if(umsg == WM_SETFOCUS)
   {
      //! Фокус на троку ввода
      SetFocus(combo_ext);
   }
   else if(umsg == WM_COMMAND)
   {
      var CODE = HIWORD(wparam);
      var IDC  = LOWORD(wparam);
      if(CODE == BN_CLICKED)
      {
         if(IDC == IDC_SET)
         {
            //! Нажата кнопка установить
            var ext = GetWindowText(combo_ext);
            if(   AkelPad.IsPluginRunning("Coder::CodeFold") ||
               AkelPad.IsPluginRunning("Coder::HighLight") ||
               AkelPad.IsPluginRunning("Coder::AutoComplete"))
            {
               AkelPad.Call("Coder::Settings",1,ext);
            }
            //AkelPad.SendMessage(hwnd,WM_CLOSE, 0, 0);
         }
         else if(IDC == IDC_EXIT)
         {
            //! Нажата кнопка выйти.
            AkelPad.SendMessage(hwnd,WM_CLOSE, 0, 0);
         }
      }
      return 0;
   }
   else if(umsg == WM_SIZE)
   {
      //! Меняем Drag&Drob область за размером панельки
      if(g_pDock)
      {
         GetWindowRect(g_hDockWnd,g_pDock+36);
         var szL = AkelPad.MemRead(g_pDock+36, 3 /*DT_DWORD*/);
         var szT = AkelPad.MemRead(g_pDock+40, 3 /*DT_DWORD*/);
         var szR = AkelPad.MemRead(g_pDock+44, 3 /*DT_DWORD*/);
         var szB = AkelPad.MemRead(g_pDock+48, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
         AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
      }
   }
   else if(umsg == WM_CLOSE)
   {
      //! Нас закрывают.
      DestroyWindow(hwnd);
      return 1;
   }
   else if(umsg == WM_DESTROY)
   {
      //! Закрыли нас.
      try
      {
         WshShell.RegWrite("HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\SetCoderExt\\Side",
               AkelPad.MemRead(g_pDock+16, 3 /*DT_DWORD*/),"REG_DWORD");
      }catch(e){}
      AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_UNSUBCLASS,g_pDock);
      AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
      g_pDock = 0;
      AkelPad.SendMessage(g_hAkelPad, AKD_RESIZE, 0, 0);
      //! Убрать сабкласинг
      AkelPad.WindowUnsubClass(combo_ext);
      g_hDockWnd = 0;
      //! Выйти из цикла
      PostQuitMessage(0);
      return 0;
   }
   //return DefWindowProc(hwnd,umsg,wparam,lparam);
   return 0;
}
//! Проверка на однократный запуск скриптам
//! Используется вместе с AkelPad.ScriptNoMutex();
//! Типичное использование:
//! 1. При первом запуске скрипта, скрипт должен создать в системе объект с помощью которого можно
//!    будет с ним связаться, например окно(видимое или невидимое), объект синхронизации(событие),
//!    именованный канал, сокетом или прочее.
//! 2. Функция FirstInstance должна проверить наличие этого объекта(найти окно, открыть объект
//!    синхронизации, соединиться с каналом или сокетом).
//! 3. По желанию программиста(по заданию), функция может сразу попытаться прервать работу первого скрипта
//!    (как это сделано в этом примере)либо вернуть идентификатор объекта, через который будет осуществляться управление
//! 4. При отсутствии такого объекта(первый запуск), скрипт инициализируется, потом должен создать связной объект,
//!    и приготовившись взаимодействовать с ним, делает вызов AkelPad.ScriptNoMutex() которые и даст работать
//!    другим скриптам(в том числе второму экземпляру). После успешного вызова скрипт может делать свою фоновую
//!    задачу или просто ждать внешней команды.
//!
//!    В этом примере:
//!     1. Скрипт регистрирует оконный класс и создает окно(который и служит объектом взаимодействия)
//!     2. В случае успеха вызывается AkelPad.ScriptNoMutex(), иначе - завершение
//!     3. Пользователь взаимодействует с окном, и закрыв его завершает скрипт
//!     4. При повторном вызове, скрипт находит окно, и закрывает его(в следствии чего и завершается первый скрипт),
//!        после чего завершается сам.
//!
//! ВАЖНО: такой фоновый скрипт разрешает полное взаимодействие с окнами редактора, потому для корректной работы
//! скрипа должен уметь определять момент когда ему нужно завершится досрочно(например, при закрытии редактора,
//! при закрытии рабочего окна, при выключении зависимых плагинов)
function FirstInstance()
{
   var dock = FindWindowEx(g_hAkelPad,DOCKCLASSNAME);
   if(dock)
   {
      AkelPad.SendMessage(dock, WM_CLOSE, 0, 0);
      return false;
   }
   else
      return true;
}

if(FirstInstance())
{
   //! Регистрируем класс окна
   var res = AkelPad.WindowRegisterClass(DOCKCLASSNAME);
   
   //! Создаем панельку
   if(CreateDock())
   {
      //! Сабкласим главное окно
      if(AkelPad.WindowSubClass( WSC_MAINPROC, AkelPadCallBack,AKDN_MAIN_ONFINISH))
      {
         //! Мы инициализировались, можно дать работать другим скриптам
         AkelPad.ScriptNoMutex();
         //! Поток в цикл сообщений
         AkelPad.WindowGetMessage();
         //! Вышли(только по закрытии панельки)
         AkelPad.WindowUnsubClass( WSC_MAINPROC );
         //! Сняли хук
      }
      if(g_hDockWnd != 0)
      {
         //AkelPad.MessageBox(0, "Text", "Caption", 0 /*MB_OK*/);
         //! По идее сюда не попадем
         AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
         g_hDockWnd = 0;
      }
   }
   //! Класс долой
   AkelPad.WindowUnregisterClass(DOCKCLASSNAME);
   //! Вернуть фокус
   SetFocus(g_hAkelPad);
   //! Взводим флаг разрешения выхода из скрипта.
   QuitMutext = true;
}
///// UTILITY
///// HELPERS: функции для упрощения системных вызовов
//! Поиск окна в пределах рабочего стола по родителю и имени класса
function FindWindowEx(hwndParent,lpszClassName)
{
   var memclass =0;
   var t = "" + lpszClassName;
   memclass = AkelPad.MemAlloc((t.length+1)*_TSIZE);
   AkelPad.MemCopy(memclass, t, _TSTR);
   var hwnd = oSys.Call("user32::FindWindowEx"+_TCHAR, hwndParent,0,memclass,0);
   AkelPad.MemFree(memclass);
   return hwnd;
}
//! Создаёт окно
function CreateWindowEx(styleex,_class,title,style,x,y,cx,cy,parent,menu,lparam)
{
   //! Нативные строки
   var mem_class = AkelPad.MemAlloc((_class.length+1)*_TSIZE);
   AkelPad.MemCopy(mem_class, _class, _TSTR);
   var mem_title = AkelPad.MemAlloc((title.length+1)*_TSIZE);
   AkelPad.MemCopy(mem_title, title, _TSTR);
   var hwnd = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                     styleex,            //! Расширенный стиль
                     mem_class,         //! Класс окна
                     mem_title,         //! Заголовок окна
                     style,            //! Стиль окна
                     x,y,cx,cy,         //! Координаты и размер
                     parent, menu,         //! Родитель и меню(идентификатор)
                     g_hModuleDll,         //! принадлежность коду
                     lparam);            //! Доп. параметр
   //! Освободить память
   AkelPad.MemFree(mem_class);
   AkelPad.MemFree(mem_title);
   return hwnd;
}
//! Показать окно, SW_* константы
function ShowWindow(hwnd,how)
{
   return oSys.Call("user32::ShowWindow",hwnd,how);
}
//! Обновить окно
function UpdateWindow(hwnd)
{
   return oSys.Call("user32::UpdateWindow",hwnd);
}
//! Выйти из оконного цикла
function PostQuitMessage(code)
{
   return oSys.Call("user32::PostQuitMessage",code);
}
//! Уничтожить окно
function DestroyWindow(hwnd)
{
   return oSys.Call("user32::DestroyWindow",hwnd);
}
//! Получить размер окна
function GetWindowRect(hwnd,rc)
{
   return oSys.Call("user32::GetWindowRect",hwnd,rc);
}
//! Дать фокус
function SetFocus(hwnd)
{
   return oSys.Call("user32::SetFocus",hwnd);
}
//! Получить текст окна
function GetWindowText(hwnd)
{
   //! Получить размер текста
   var res = AkelPad.SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
   //! Выделить память
   var mem = AkelPad.MemAlloc((res+2)*_TSIZE);
   //! Полчиуть текст
   AkelPad.SendMessage(hwnd, WM_GETTEXT,res+1, mem);
   var str = AkelPad.MemRead(mem, _TSTR);
   //! Освободить память
   AkelPad.MemFree(mem);
   return str;
}
//! Получить состояние кнопки
function GetKeyState(key)
{
   return oSys.Call("user32::GetKeyState",key);
}
//! LOWORD
function LOWORD(long)
{
   return long & 0x0FFFF;
}
//! HIWORD
function HIWORD(long)
{
   return (long >> 16) & 0x0FFFF;
}
//! MAKEWPARAM
function MAKEWPARAM(l, h)
{
   return MAKELONG(l, h);
}
//! MAKELONG
function MAKELONG(l, h)
{
   return (l & 0x0FFFF) + ((h & 0x0FFFF) << 16);
}
///// UNUSED HELPERS, STILL CAN BE USEFUL IN FUTURE
//! Системная оконная процедура
////function DefWindowProc(hwnd,umsg,wparam,lparam)
////{
////   return oSys.Call("user32::DefWindowProc"+_TSTR,hwnd,umsg,wparam,lparam);
////}
//! Получить контекст рисования
////function BeginPaint(hwnd,ps)
////{
////   return oSys.Call("user32::BeginPaint",hwnd,ps);
////}
//! Закончить рисование
////function EndPaint(hwnd,ps)
////{
////   return oSys.Call("user32::EndPaint",hwnd,ps);
////}
//! Перерисовать область окна
////function InvalidateRect(hwnd,rect,erase)
////{
////   return oSys.Call("user32::InvalidateRect",hwnd,rect,erase);
////}
/*****************************************************
   Manuals
*****************************************************/
/***
   typedef struct _DOCK {
0   struct _DOCK *next;
4   struct _DOCK *prev;
8   DWORD dwFlags;         //Dock flags: see DKF_* defines.
12   HWND hWnd;         //Dock window handle.
16   int nSide;         //Dock side: DKS_LEFT, DKS_TOP, DKS_RIGHT or DKS_BOTTOM.
20   RECT rcSize;         //Dock window client RECT.
20   .left
24   .top
28   .right
32   .bottom
36   RECT rcDragDrop;      //Drag-and-drop client RECT.
36   .left
40   .top
44   .right
48   .bottom
   } DOCK;
***/


Last edited by FeyFre on Sat Apr 19, 2014 6:03 pm; edited 2 times in total
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Infocatcher



Joined: 06 Aug 2007
Posts: 1570

PostPosted: Sat Jan 08, 2011 5:50 pm    Post subject: Reply with quote

backupVersion.js
Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10791#10791
// http://infocatcher.ucoz.net/js/akelpad_scripts/backupVersion.js

// (c) Infocatcher 2011
// version 0.1.4 - 2011-12-20

//===================
// Tries find file version and copy current file to the same directory:
//   file.js      -> file-%version%.js
//   file.user.js -> file-%version%.user.js

// Usage:
//   Call("Scripts::Main", 1, "backupVersion.js")
//===================

//== Settings begin
var getVersionPattern  = /(^|[^a-z])(version|v\.)[ \t]*[-:=]?[ \t]*(\S+)/i;
var versionBracketsNumber = 3; // We don't use (?:something) for backward compatibility with old JScript
var testVersionPattern = /\d/; // Version string must contain number
var linesLimit = 20; // Check only first 20 lines of file
var addVersionPattern = /(\.[^.\d]+)*$/; // {fileName}{versionSeparator}{version}{addVersionPattern}
function getVersionSeparator(version) {
   return /-/.test(version) ? "_" : "-";
}
var dateTypesCount = 3;
function dateToString(date, type) {
   function pad(n) {
      return n < 10 ? "0" + n : n;
   }
   var ret = date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate());
   if(type == 0)
      return ret;
   ret += "_" + pad(date.getHours()) + "-" + pad(date.getMinutes());
   if(type == 1)
      return ret;
   ret += "-" + pad(date.getSeconds());
   return ret;
}
function trimVersion(version) {
   return version
      .replace(/^v\.?\s*/i, "")
      .replace(/[.,]+$/, "");
}
//== Settings end

function _localize(s) {
   var strings = {
      "Save file first!": {
         ru: "Сначала сохраните файл!"
      },
      "Can't detect file version!": {
         ru: "Не удалось определить версию файла!"
      },
      "Can't use original file name!": {
         ru: "Нельзя использовать имя исходного файла!"
      },
      "File “%S” already exists!\nOverwrite?": {
         ru: "Файл «%S» уже существует!\nПерезаписать?"
      },
      "Can't copy current file to “%F”\nError:\n%E": {
         ru: "Не удалось копировать текущий файл в «%F»\nОшибка:\n%E"
      },
      "Backup file was succefully created:\n%S": {
         ru: "Файл резервной копии успешно создан:\n%S"
      },
      "Name of backup file:": {
         ru: "Имя файла резервной копии:"
      }
   };
   var lng;
   switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
      case 0x19: lng = "ru"; break;
      default:   lng = "en";
   }
   _localize = function(s) {
      return strings[s] && strings[s][lng] || s;
   };
   return _localize(s);
}

var hMainWnd = AkelPad.GetMainWnd();
if(!hMainWnd)
   WScript.Quit();

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var fso = new ActiveXObject("Scripting.FileSystemObject");
var curPath = AkelPad.GetEditFile(0);
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

if(!curPath) {
   AkelPad.MessageBox(hMainWnd, _localize("Save file first!"), dialogTitle, 48 /*MB_ICONEXCLAMATION*/);
   WScript.Quit();
}

copyFile();

function copyFile() {
   var curName = fso.GetFileName(curPath);
   var curDir  = fso.GetParentFolderName(curPath);
   var newName;
   var overwrite = false;
   var exists = function(name) {
      var path = curDir + "\\" + name;
      return fso.FileExists(path) || fso.FolderExists(path);
   };
   var version = getVersion();
   if(version)
      newName = curName.replace(addVersionPattern, getVersionSeparator(version) + version + "$&");
   else {
      var askName = curName;
      var lastMod = new Date(fso.GetFile(curPath).DateLastModified);
      for(var i = 0; i < dateTypesCount; i++) {
         var lastModStr = dateToString(lastMod, i);
         var testName = curName.replace(addVersionPattern, getVersionSeparator(lastModStr) + lastModStr + "$&");
         if(!exists(testName)) {
            askName = testName;
            break;
         }
      }
      AkelPad.MessageBox(hMainWnd, _localize("Can't detect file version!"), dialogTitle, 48 /*MB_ICONEXCLAMATION*/);
      newName = askFileName(askName);
      if(!newName)
         return;
   }
   for(;;) {
      if(newName == curName) {
         AkelPad.MessageBox(
            hMainWnd,
            _localize("Can't use original file name!"),
            dialogTitle,
            48 /*MB_ICONEXCLAMATION*/
         );
      }
      else {
         if(!exists(newName) && _copy(curPath, curDir, newName, overwrite))
            break;

         var btn = AkelPad.MessageBox(
            hMainWnd,
            _localize("File “%S” already exists!\nOverwrite?").replace("%S", newName),
            dialogTitle,
            35 /*MB_YESNOCANCEL|MB_ICONQUESTION*/
         );
         if(btn == 2 /*IDCANCEL*/)
            return;
         overwrite = btn == 6 /*IDYES*/;
         if(overwrite && _copy(curPath, curDir, newName, overwrite))
            break;
      }
      newName = askFileName(newName);
      if(!newName)
         return;
   }
}
function askFileName(fileName) {
   return AkelPad.InputBox(hMainWnd, dialogTitle, _localize("Name of backup file:"), fileName);
}
function _copy(curPath, curDir, newName, overwrite) {
   try {
      fso.CopyFile(curPath, curDir + "\\" + newName, overwrite);
   }
   catch(e) {
      AkelPad.MessageBox(
         hMainWnd,
         _localize("Can't copy current file to “%F”\nError:\n%E")
            .replace("%F", newName)
            .replace("%E", e.message || e),
         dialogTitle,
         16 /*MB_ICONQUESTION*/
      );
      return false;
   }
   //if(overwrite)
   //   return true;
   new ActiveXObject("WScript.Shell").Popup(
      _localize("Backup file was succefully created:\n%S").replace("%S", newName),
      2, // Autoclose after 2 seconds
      dialogTitle,
      64 /*MB_ICONINFORMATION*/
   );
   return true;
}
function getVersion() {
   var version = "";

   var ww = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
   if(ww) {
      setRedraw(hWndEdit, false);
      AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
   }

   var lineStart = 0;
   var line = 0;
   var linesCount = AkelPad.SendMessage(hWndEdit, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
   var maxLine = Math.min(linesLimit, linesCount) - 1;
   for(;;) {
      var lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, lineStart, 0);
      var lineEnd    = lineStart + lineLength;
      var lineText   = AkelPad.GetTextRange(lineStart, lineEnd);

      if(getVersionPattern.test(lineText)) {
         var tmp = RegExp["$" + versionBracketsNumber];
         if(testVersionPattern.test(tmp)) {
            version = trimVersion(tmp);
            break;
         }
      }

      lineStart = lineEnd + 1;
      if(++line > maxLine)
         break;
   }

   if(ww) {
      AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
      setRedraw(hWndEdit, true);
   }

   return version;
}
function setRedraw(hWnd, bRedraw) {
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Tries find file version and copy current file to the same directory:
file.js -> file-%version%.js
file.user.js -> file-%version%.user.js


Last edited by Infocatcher on Tue Jan 03, 2012 11:25 pm; edited 4 times in total
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 5174

PostPosted: Mon Jan 10, 2011 4:29 pm    Post subject: Reply with quote

Delete record from recent files.

DeleteRecentFile.js

Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#10810
// Version v1.1
//
//
//// Delete record from recent files.
//
// Example via ContextMenu plugin:
// Call("Scripts::Main", 1, "DeleteRecentFile.js", `'%f'`)

var hMainWnd=AkelPad.GetMainWnd();

if (WScript.Arguments.length)
  DeleteRecentFile(WScript.Arguments(0));

function DeleteRecentFile(pFileToDelete)
{
  var nIndex;

  if ((nIndex=AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 7 /*RF_FINDINDEX*/, AkelPad.MemStrPtr(pFileToDelete))) >= 0)
  {
    if (AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 8 /*RF_DELETEINDEX*/, nIndex))
      AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 4 /*RF_SAVE*/, 0);
  }
}




Clear recent files list.

ClearRecentFiles.js

Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#10810
// Version: 1.0
//
//// Clear recent files list.
//
// Arguments:
// -Msg=false  -Clear recent files list without prompt (default is true).
//
// Usage:
// -"Clear list" Call("Scripts::Main", 1, "ClearRecentFiles.js", `-Msg=false`)

var hWndMain=AkelPad.GetMainWnd();

if (AkelPad.GetArgValue("Msg", true))
{
  if (AkelPad.MessageBox(hWndMain, GetLangString(0), WScript.ScriptName, 0x24 /*MB_ICONQUESTION|MB_YESNO*/) == 7 /*IDNO*/)
    WScript.Quit();
}
AkelPad.SendMessage(hWndMain, 1238 /*AKD_RECENTFILES*/, 5 /*RF_CLEAR*/, 0);
AkelPad.SendMessage(hWndMain, 1238 /*AKD_RECENTFILES*/, 4 /*RF_SAVE*/, 0);


function GetLangString(nStringID)
{
  var nLangID=AkelPad.GetLangId(1 /*LANGID_PRIMARY*/);

  if (nLangID == 0x19) //LANG_RUSSIAN
  {
    if (nStringID == 0)
      return "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u0020\u0441\u043F\u0438\u0441\u043E\u043A\u0020\u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445\u0020\u0444\u0430\u0439\u043B\u043E\u0432\u003F";
  }
  else
  {
    if (nStringID == 0)
      return "Clear recent files list?";
  }
  return "";
}




Open closed file.

OpenClosedRecentFile.js

Code:
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#10810
// Version v1.0
//
//
//// Open closed file.
//
// Example:
// Call("Scripts::Main", 1, "OpenClosedRecentFile.js")

var hMainWnd=AkelPad.GetMainWnd();
var nMaxRecentFiles;
var lppStack;
var lpStack;
var lpRecentFile;
var pFile;

if (lppStack=AkelPad.MemAlloc(_X64?8:4 /*sizeof(RECENTFILESTACK **)*/))
{
  if (nMaxRecentFiles=AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 1 /*RF_GET*/, lppStack))
  {
    lpStack=AkelPad.MemRead(lppStack, 2 /*DT_QWORD*/);
    lpRecentFile=AkelPad.MemRead(lpStack + 0 /*offsetof(RECENTFILESTACK, first)*/, 2 /*DT_QWORD*/)

    while (lpRecentFile)
    {
      pFile=AkelPad.MemRead(lpRecentFile + (_X64?16:8) /*offsetof(RECENTFILE, wszFile)*/, 1 /*DT_UNICODE*/);
      if (!AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 5 /*FWF_BYFILENAME*/, pFile))
      {
        AkelPad.OpenFile(pFile);
        break;
      }
      lpRecentFile=AkelPad.MemRead(lpRecentFile + 0 /*offsetof(RECENTFILE, next)*/, 2 /*DT_QWORD*/)
    }
  }
  AkelPad.MemFree(lppStack);
}



Last edited by Instructor on Sat Mar 22, 2014 8:36 pm; edited 7 times in total
Back to top
View user's profile Send private message Send e-mail
lexa



Joined: 14 Jan 2011
Posts: 19

PostPosted: Fri Jan 14, 2011 4:25 am    Post subject: Reply with quote

1. "Кавычкер"

Меняет кавычки на "елочки", а вложенные кавычки на другие кавычки "лапки":
Quote:
Вася сказал: "Я живу в отеле "Калифорния""

Quote:
Вася сказал: «Я живу в отеле „Калифорния“».


Подробнее на http://spectator.ru/technology/php/quotation_marks_stike_back.

Автор Дима Смирнов.

Изначальный вариант предполагает замену на HTML-значения (вроде &#151 для тире). Вариант ниже для чистого текста поэтому неразрывные пробелы и <nobr /> не вошли в скрипт, а специальные символы преобрели первозданный вариант. Работает с cp1251.

Kavychker.js
Code:
// Apply russian basic typography rules.
//
// Version: 1.0 (2011/01/14)
// Author: Dmitry Smirnov <http://spectator.ru>

var s = AkelPad.GetSelText();

if (!s){
    s = AkelPad.GetTextRange(0, -1);
    AkelPad.SetSel(0, -1);
}

s = ' ' + s;

// кавычки

// put in array
var a = s.match(/<([^>]*)>/g);

var i = 0;
var r = /<([^>]*)>/;

while (r.test(s))
    s = s.replace(r, '\x01' + ++i + '\x02');

// wordfix
s = s.replace(/«/g, '"');
s = s.replace(/»/g, '"');
s = s.replace(/“/g, '"');
s = s.replace(/”/g, '"');
s = s.replace(/…/g, '...');
s = s.replace(/–/g, '-');
s = s.replace(/—/g, '-');

// kavychking
s = s.replace(/([\x01-(\s\"])(\")([^\"]{1,})([^\s\"(])(\")/g, '$1«$3$4»');

// kavychking in kavychking
if (/"/.test(s)){
    s = s.replace(/([\x01(\s\"])(\")([^\"]{1,})([^\s\"(])(\")/g, '$1«$3$4»');
   
    while (/(«)([^»]*)(«)/.test(s))
        s = s.replace(/(«)([^»]*)(«)([^»]*)(»)/g, '$1$2„$4“');
}

s = s.replace(/  +/g, ' ');

s = s.replace(/ -{1,2} /g, ' — ');
s = s.replace(/\.{3}/g, '…');
s = s.replace(/([>|\s])- /g, '$1— ');
s = s.replace(/^- /g, '— ');

s = s.replace(/(\d)-(\d)/g, '$1–$2');

// инициалы

// A.C. Пушкин
s = s.replace(/([А-ЯA-Z])([\. ]{1})[ ]{0,1}([А-ЯA-Z])([\. ]{1})[ ]{0,1}([А-ЯA-Z][А-Яа-яA-Za-z]*)/g, '$1. $3. $5');

// Пушкин А. С.
s = s.replace(/([А-ЯA-Z][А-Яа-яA-Za-z]*) ([А-ЯA-Z])[\. ]{1}[ ]{0,1}([А-ЯA-Z])\.([,\ )]{1})/g, '$1 $2. $3.$4');

// (А.С.Пушкин) 
 // (Пушкин А.С)
 // (Пушкин А. С)

s = s.replace(/'/g, '’');
s = s.replace(/\(c\)/gi, '©');
s = s.replace(/\(r\)/gi, '®');
s = s.replace(/\(tm\)/gi, '™');
s = s.replace(/№ /gi, '№');

// out array
i = 0;
r = /\x01([0-9]*)\x02/;

while (r.test(s))
    s = s.replace(r, a[++i - 1]);

AkelPad.ReplaceSel(s.substr(1));



2. SmartBackspace

Такое уже есть в пожеланиях, но пока нет официальной реализации внутри редактора, есть криворукий вариант через скрипты. Smile

Что делает: удаляет пробелы и табы по несколько штук за раз, а не по одному пробелу. Умеет упираться в начало блока текста предыдущей строки:
Code:
if (i){
        var j; // Начало блока
        |<--------отсюда туда
|<----потом сюда
}


[выпилил]

upd добавил шапку-комментарий, как советовали, но моя английский говорить плохо. Поэтому... да. Smile


Last edited by lexa on Sun Jan 23, 2011 8:37 am; edited 2 times in total
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Plugins All times are GMT
Goto page Previous  1, 2, 3 ... 7, 8, 9 ... 16, 17, 18  Next
Page 8 of 18

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


SourceForge.net Logo Powered by phpBB © 2001, 2005 phpBB Group