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 

AkelEmmet - Emmet (ex Zen Coding) wrapper for AkelPad

 
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (English)
View previous topic :: View next topic  
Author Message
beotiger



Joined: 09 Dec 2015
Posts: 48

PostPosted: Tue Jan 05, 2016 7:33 pm    Post subject: AkelEmmet - Emmet (ex Zen Coding) wrapper for AkelPad Reply with quote

AkelEmmet

AkelEmmet is an Emmet http://emmet.io (ex Zen Coding) wrapper for AkelPad.

Upgrade to AkelEmmet 1.2! How to upgrade

If you have AkelEmmet 1.0 or AkelEmmet 1.1 please upgrade to AkelEmmet 1.2. To upgrade download new archive from location below and unpack it to [AkelPad]\AkelFiles\Plugs\Scripts. You can remove folder [AkelPad]\AkelFiles\Tools\emmet then. Do not forget to move your snippets and extensions if you have ones from Tools\emmet\ext folder to Plugs\Scripts\Include\Emmet\ext. Change menu entries for Context::Menu Edit and ToolBar menu to set new path to icon_16.ico as shown below.



Screenshot 1
Screenshot 2



You need Scripts plugin to run this AkelEmmet wrapper. All other plugins are optional.


1. Installation

1.1 Downloading and unpacking

Download AkelEmmet 1.2 and unzip it to [AkelPad]\AkelFiles\Plugs\Scripts


1.2 Add menu entries for toolbar and context menu (optional)
Note: for menu entries you need ToolBar and ContextMenu plugins.

Call ContextMenu::Main plugin function (Options - Plug-ins...) and add following code at the end of ContextMenu::ShowMenu section:
# AkelEmmet Context::Menu Show menu
Code:
"EMMET"
{
   "Expand Abbreviation" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=0')
   "Wrap with Abbreviation" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=3')
   "Balance Tag" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=1')
   "Balance Tag Inward" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=2')
   "Next Edit Point" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=4')
   "Previous Edit Point" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=5')
   SEPARATOR1
   "Merge Lines" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=6')
   "Remove Tag" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=7')
   "Split/Join Tag" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=8')
   "Toggle Comment" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=9')
   SEPARATOR1
   "Select Next Item" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=17')
   "Select Previous Item" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=18')
   "Reflect CSS Value" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=19')
   SEPARATOR1
   "Evaluate Math Expresison" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=10')
   "Increment Number By 1" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=11')
   "Decrement Number By 1" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=12')
   "Increment Number By 0.1" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=13')
   "Decrement Number By 0.1" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=14')
   "Increment Number By 10" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=15')
   "Decrement Number By 10" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=16')
   SEPARATOR1
   "Update Image Size" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=20')
   "Encode/Decode image to data:URL" Call("Scripts::Main", 1, "AkelEmmet.js", '-action=21')
}


Now add following code in ContextMenu::Edit menu section:
# AkelEmmet Context::Menu Edit menu
Code:
SEPARATOR1
   "Emmet" Menu("EMMET") Icon("%a\AkelFiles\Plugs\Scripts\Include\Emmet\icon_16.ico")


Click right mouse button on any place inside tool bar and add the following code at place you like most
# AkelEmmet ToolBar menu
Code:
SEPARATOR1
"Emmet: Expand Abbreviation"  Call("Scripts::Main", 1, "AkelEmmet.js", '-action=0') Menu("EMMET") Icon("%a\AkelFiles\Plugs\Scripts\Include\Emmet\icon_16.ico")
SEPARATOR1


1.3 Adding hotkey
Add hotkey [Ctrl+Enter] (or any of your choice) for calling AkelEmmet.js script.
Its default action is 'expand_abbreviation' - that is expand abbreviation.
You can do this by calling Scripts::Main (Alt-p, Scripts::Main, [Call]) and assigning key for AkelEmmet.js script.

To make hotkeys for various Emmet actions you need Hotkeys plugin.
To see some Emmet's logs you need to have Log plugin installed.

All plugins mentioned here are official and can be downloaded
from official plugins page at http://akelpad.sourceforge.net/en/plugins.php


2. Usage.
Call AkelEmmet.js with parameter `action` to exec any of supported Emmet actions.
`action` can be # of command from list (see source of AkelEmmet.js for full list of commands)
or name of Emmet action, e.g. 'match_pair_outward' or 'toggle_comment'

Examples:
Call("Scripts::Main", 1, "AkelEmmet.js") - to run default action which is 'expand_abbreviation'
Call("Scripts::Main", 1, "AkelEmmet.js", `-action=4`) - to run 'next_edit_point' action
Call("Scripts::Main", 1, "AkelEmmet.js", `-action='select_next_item'`) - to select next item
and so on.

You can set hotkeys for desired commands through Hotkey plugin.

Recommended hotkeys (its up to you):
[Ctrl+Enter] Expand Abbreviation Call("Scripts::Main", 1, "AkelEmmet.js")
[Ctrl+Shift+Enter] Wrap with Abbreviation Call("Scripts::Main", 1, "AkelEmmet.js", `-action=3`)
[Ctrl+Alt+Right] Emmet next edit point Call("Scripts::Main", 1, "AkelEmmet.js", `-action=4`)
[Ctrl+Alt+Left] Emmet previous edit point Call("Scripts::Main", 1, "AkelEmmet.js", `-action=5`)
[Alt+T] Toggle comment Call("Scripts::Main", 1, "AkelEmmet.js", `-action='toggle_comment'`)
* Note: toggle comment works for HTML/CSS files

3. Test
Type in abbreviation and press [Ctrl+Enter] if you defined it as a hotkey for default Emmet action to expand it.

Open empty document (Ctrl+n), type in following abbreviation and expand it:

Code:
!(h1{Hello world!}+ul>li*5>lorem50^^h1{Bye-bye})


Then save it as hi-emmet.html (Ctrl+s) for example and run it in your browser.

Some more HTML snippets to test
Code:
div>ul>li*5>b
p*5>lorem12(span.span-deva$*3>b{This is my span #$})
div#content>h1+p
div#page>div.logo+ul#navigation>li*5>a[style="text-decoration: none" id="link$$"]
table>(tr.g$>td^tr>td)*3
{Item$${newline}}*3
html:xs


To test some CSS snippets open css file and try to expand following abbreviations
Code:
w100
h10p+m5e
@f
@f+
tdn
posrel
ov-h
ovh
oh
trs
trf
-super-foo
-wm-trf
lg(left, #fff 50%, #000)
lorem10
pb
p10p
db+w100+h100+posa+l-100+t60


Note that same abbreviation for css and html files can expand differently.


4. Extending
You can put Emmet extensions into `Include\Emmet\ext` folder.

Extensions are simple .js files that uses Emmet modules and resources
to create new actions, modify existing ones etc.

When any Emmet action starts, all `*.js` files in `Include\Emmet\ext` folder will be eval'ed,
and all `snippets*.json` files will extend `snippets` Emmet object.

It allows you to extend and rewrite Emmet behaviour and snippets any way you want.

That's all. Good coding.
--
beotiger

P.S.
License and guarantee information
Code:

The MIT License (MIT)

Copyright (c) 2012 Sergey Chikuyonok <serge.che@gmail.com>
Support for AkelPad by beotiger http://beotiger.com 2016-01-05

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Last edited by beotiger on Thu Jan 07, 2016 10:04 am; edited 3 times in total
Back to top
View user's profile Send private message
FeyFre



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

PostPosted: Tue Jan 05, 2016 11:29 pm    Post subject: Reply with quote

1. Рекомендую за рамки принятых каталогов не вылезять:
скрипты которые вызываются - в Scripts
скрипты которые используются другими скриптами и никогда не вызываются пользователем - в Scripts/Include
Далее 1: AkelEmmet.js и прочие

eval(AkelPad.ReadFile(...)); обязательно заменить на AkelPad.Include(). Поверьте на слово.

Далее 2: editor.js

Code:
      getCurrentLine: function() {
         var range = this.getCurrentLineRange();
         var nSelStart = AkelPad.GetSelStart(),
               nSelEnd = AkelPad.GetSelEnd();
               
               
         AkelPad.SetSel(range.start, range.end);
         var text = AkelPad.GetSelText();
         // restore selection
         AkelPad.SetSel(nSelStart, nSelEnd);
         return text;
      },
нужно сделать так
Code:
getCurrentLine: function() {
         var range = this.getCurrentLineRange();
         return AkelPad.GetTextRange(range.start, range.end);
      }
т.е. нет абсолютно никакой необходимости играться выделениями.

Далее 3: editor.js
Code:
      getSyntax: function(){
         return require('actionUtils').detectSyntax(this,
            AkelPad.GetFilePath(this.getFilePath(), 4 /*FILE_EXT*/).toLowerCase());
      },
Этот код может и должен быть улучшен, а именно: перед ориентацией на расширение рекомендуется спросить в других местах текущий контекст, например у плагина Coder

ЗЫ:
beotiger, у вас то руки раньше дошли чем у меня.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
beotiger



Joined: 09 Dec 2015
Posts: 48

PostPosted: Thu Jan 07, 2016 10:19 am    Post subject: Reply with quote

FeyFre wrote:
1. Рекомендую за рамки принятых каталогов не вылезять:
скрипты которые вызываются - в Scripts
скрипты которые используются другими скриптами и никогда не вызываются пользователем - в Scripts/Include
Далее 1: AkelEmmet.js и прочие

eval(AkelPad.ReadFile(...)); обязательно заменить на AkelPad.Include(). Поверьте на слово.

Далее 2: editor.js

Code:
      getCurrentLine: function() {
         var range = this.getCurrentLineRange();
         var nSelStart = AkelPad.GetSelStart(),
               nSelEnd = AkelPad.GetSelEnd();
               
               
         AkelPad.SetSel(range.start, range.end);
         var text = AkelPad.GetSelText();
         // restore selection
         AkelPad.SetSel(nSelStart, nSelEnd);
         return text;
      },
нужно сделать так
Code:
getCurrentLine: function() {
         var range = this.getCurrentLineRange();
         return AkelPad.GetTextRange(range.start, range.end);
      }
т.е. нет абсолютно никакой необходимости играться выделениями.

Далее 3: editor.js
Code:
      getSyntax: function(){
         return require('actionUtils').detectSyntax(this,
            AkelPad.GetFilePath(this.getFilePath(), 4 /*FILE_EXT*/).toLowerCase());
      },
Этот код может и должен быть улучшен, а именно: перед ориентацией на расширение рекомендуется спросить в других местах текущий контекст, например у плагина Coder

ЗЫ:
beotiger, у вас то руки раньше дошли чем у меня.


FeyFre спасибо за замечания! Все они учтены в новой версии скрипта - AkelEmmet 1.2.
Так же скрипт получил новую постоянную локацию - http://akelpad.sourceforge.net/forum/viewtopic.php?p=30266#30266

FeyFre thanks for your notes. They have been taken into consideration and new version of AkelEmmet is out. It's faster and better due to you!
Also AkelEmmet got new persistent location - http://akelpad.sourceforge.net/forum/viewtopic.php?p=30266#30266
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 6164

PostPosted: Thu Jan 07, 2016 12:23 pm    Post subject: Reply with quote

beotiger
file.js wrote:
function WriteFile(sFile, sData)
AkelPad.WriteFile?

Юникод кодировку скрипта (AkelEmmet.js) лучше использовать с BOM.
Back to top
View user's profile Send private message Send e-mail
KDJ



Joined: 06 Mar 2010
Posts: 1859
Location: Poland

PostPosted: Thu Jan 07, 2016 8:02 pm    Post subject: Reply with quote

beotiger
I wrote WriteFile function at a time when there was no WriteFile method in Scripts plugin.
Now you can use AkelPad.WriteFile instead of WriteFile.
Back to top
View user's profile Send private message
beotiger



Joined: 09 Dec 2015
Posts: 48

PostPosted: Fri Jan 08, 2016 11:22 am    Post subject: Reply with quote

Instructor wrote:
beotiger
file.js wrote:
function WriteFile(sFile, sData)
AkelPad.WriteFile?

AkelPad.ReadFile
Code:
Read contents of a file.

  ReadFile(pFile[, nFlags][, nCodePage][, bBOM][, nBytesMax]);



AkelPad.WriteFile
Code:
Write file content.

  WriteFile(vFile, pContent, nContentLen, nCodePage, bBOM[, nFlags]);



Меня смущает, что при записи файла обязательно указывать кодировку, тогда как при чтении её можно опустить.

Какую кодировку указывать при записи бинарных данных?
Никаких преобразований над бинарными данными не делается?


Instructor wrote:
Юникод кодировку скрипта (AkelEmmet.js) лучше использовать с BOM.

Причина?
Back to top
View user's profile Send private message
FeyFre



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

PostPosted: Fri Jan 08, 2016 12:02 pm    Post subject: Reply with quote

beotiger, забудь о бинарных данных. Все строки которые ходят внутри АР и в плагинах(в т.ч. скриптах) - z-строки, внутри хранятся в UTF-16 кодировке. Если что-то такое нужно делать - АР не помощник.
Для этих целей есть oSys.Call(диспетчер системных вызовов WINAPI), AkelPad.Mem*(менеджер памяти).

Quote:
Причина?
Чтобы потом можно было распознать кодировку автоматически, а не гадать на гуще. Конечно если в файле полезные данные исключительно в наборе символов iso8859-1, то не правильно распознанная кодировка данных не испортит.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Drugmix



Joined: 08 Apr 2013
Posts: 563
Location: Win7SP1x64, APx64

PostPosted: Sun Jan 10, 2016 11:10 pm    Post subject: Reply with quote

Не знал, что можно просто взять и приделать стороннюю обёртку к АкелПаду.
А все функции (хоткеи, плагины, скрипты) акелпада при этом продолжают нормально работать?
Интересно было бы пощупать AkelPad со Scintilla обёрткой.
Back to top
View user's profile Send private message
FeyFre



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

PostPosted: Mon Jan 11, 2016 10:30 am    Post subject: Reply with quote

Drugmix, больше скажу: это не первая успешная попытка прикрутить zen_coding.

Quote:
Интересно было бы пощупать AkelPad со Scintilla обёрткой.
"Установил Скайп на телефон, теперь могу пользоваться телефоном как телефоном". При таких вбросах нужно ссылку давать на испытуемое Smile
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
beotiger



Joined: 09 Dec 2015
Posts: 48

PostPosted: Thu Jan 14, 2016 7:02 pm    Post subject: Reply with quote

Drugmix wrote:
Не знал, что можно просто взять и приделать стороннюю обёртку к АкелПаду.

Emmet написан на чистом JavaScript, поэтому всю работу за нас выолняет великолепный Scripts плагин. нам надо было только переписать характерные для AkelPad'а функции редактирования текста и работы с файлами.
Drugmix wrote:
А все функции (хоткеи, плагины, скрипты) акелпада при этом продолжают нормально работать?

AkelEmmet.js - это обычный скрипт, который Вы запускате либо из Scripts плагина, либо по назначению горячих клавиш. Он никак не влияет на работу самого редактора. В нём содержатся действия Emmet'а, для которых можно также назначить горячие клавиши или пункты меню. Прочитайте AkelEmmet_readme_ru.txt для понимания ситуации.

FeyFre wrote:
Drugmix, больше скажу: это не первая успешная попытка прикрутить zen_coding.

FeyFre, там ссылки битые, может их исправить, а то они меня ввели в заблуждение.

FeyFre wrote:
Quote:
Интересно было бы пощупать AkelPad со Scintilla обёрткой.
"Установил Скайп на телефон, теперь могу пользоваться телефоном как телефоном". При таких вбросах нужно ссылку давать на испытуемое Smile

Тут имеется в виду, наверное, что если сделать обёртку Scintilla для AkelPad'а, то можно будет использовать Scintilla-плагины.
Теоретически можно наверное, только сколько это займет человеко-часов неясно. Да и зачем. У AkelPad'а своя неповторимая атмосфера и своя философия работы с текстом, по моему скромному мнению.
Back to top
View user's profile Send private message
beotiger



Joined: 09 Dec 2015
Posts: 48

PostPosted: Thu Jan 14, 2016 7:15 pm    Post subject: Reply with quote

FeyFre wrote:
beotiger, забудь о бинарных данных. Все строки которые ходят внутри АР и в плагинах(в т.ч. скриптах) - z-строки, внутри хранятся в UTF-16 кодировке. Если что-то такое нужно делать - АР не помощник.
Для этих целей есть oSys.Call(диспетчер системных вызовов WINAPI), AkelPad.Mem*(менеджер памяти).

FeyFre, на основе KDJ's FileAndStream_functions.js я написал функцию Read file
Code:
//-----------------------------------------------------
// sContent = readFile(sFile)
//
// Arguments:
// sFile   - full file name
//
// Return value:
// sContent - content of file
//-----------------------------------------------------
function ReadFile(sFile)
{
  var sContent = '',
        br;   // bytes read

  var hFromFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
                    sFile, //lpFileName
                    0x80000000, //dwDesiredAccess = GENERIC_READ
                    1,          //dwShareMode = FILE_SHARE_READ
                    0,          //lpSecurityAttributes
                    3,          //dwCreationDisposition = OPEN_EXISTING
                    0x08000000, //dwFlagsAndAttributes = FILE_FLAG_SEQUENTIAL_SCAN
                    0);         //hTemplateFile

   if(hFromFile != -1) {
     var nBufSize       = 64 * 1024;
     var lpBuffer       = AkelPad.MemAlloc(nBufSize);
     var lpBytesRead    = AkelPad.MemAlloc(4);

     do
     {
       AkelPad.SystemFunction().Call("Kernel32::ReadFile", hFromFile, lpBuffer, nBufSize, lpBytesRead, 0);
          if(br = AkelPad.MemRead(lpBytesRead, 3 /*DT_DWORD*/))   // bytes read
             sContent += AkelPad.MemRead(lpBuffer, 0 /*DT_ANSI*/, br);
     }
     while (br == nBufSize);

     AkelPad.MemFree(lpBuffer);
     AkelPad.MemFree(lpBytesRead);
     AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hFromFile);
   }
 
  return sContent;
}
, которая читает бинарный файл.
Но потом сравнил её со встроенным методом AkelPad.ReadFile и увидел, что они читают одинаково, поэтому отказался от неё.
WriteFile'же в editor.js остался, так как мне неясно, как ведет себя AkelPad.WriteFile при записи бинарников (по причине, описанной выше).
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 6164

PostPosted: Sun Feb 21, 2016 9:00 am    Post subject: Reply with quote

beotiger
file.js wrote:
AkelPad.MemCopy(lpBuffer, sData, 0);
0 это DT_ANSI. Т.е. можно заменить WriteFile на:
Code:
AkelPad.WriteFile(sFile, sData, -1, AkelPad.SystemFunction().Call("kernel32::GetACP"), false);

А с версии 4.9.8 можно использовать -1:
Code:
AkelPad.WriteFile(sFile, sData, -1, -1, false);
Back to top
View user's profile Send private message Send e-mail
LonerD



Joined: 01 Dec 2011
Posts: 145
Location: Donetsk

PostPosted: Tue May 03, 2016 12:14 pm    Post subject: Reply with quote

Balance в скрипте не работает таким образом, как продемонстрировано на сайте Emmet, или это только у меня проблемы возникли?
Выделяется только один раз, и при последующих нажатиях выделение не расширяется на теги уровнем выше.
Balance Tag Inward - в большую сторону один раз выделяется, и всё, выделение не уменьшается.

Encode/Decode Image to data:URL и Update Image Size тоже как-то непонятно - скрипт просто открывает окошко лог-файла.
Back to top
View user's profile Send private message
tmsg



Joined: 21 Aug 2012
Posts: 46
Location: UK

PostPosted: Thu May 05, 2016 5:36 pm    Post subject: Reply with quote

Discussion (English)... really?
Back to top
View user's profile Send private message
KDJ



Joined: 06 Mar 2010
Posts: 1859
Location: Poland

PostPosted: Thu May 05, 2016 5:59 pm    Post subject: Reply with quote

tmsg
Discussion is English-Russian. Smile

-----
Instructor wrote:
А с версии 4.9.8 можно использовать -1:
Code:
AkelPad.WriteFile(sFile, sData, -1, -1, false);

This is not documented in Scripts-Eng.txt.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (English) All times are GMT
Page 1 of 1

 
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