1

Тема: AHK: Быстрое обрамление текста

Скрипт PhiLho незабвенного.
Обрамляет выделенный или буферный текст чем угодно: кавычками, тегами, завитками, усиками... Не удержался, по старой привычке от того чтобы не добавить своей ложки... т.е., конечно же, капли мёда: при крепко зажатом Ctrl возможен дополнительный неоценимый сервис. Вот пример: клик по пункту меню — и выбранный текст запижонил в HTML тегах, с удержанным Ctrl — в тегах bbCode щеголяет.

#SingleInstance force

menuHTMLify =
(
Франц. «елочки»%A_Tab%Alt+0171/0187
«(&c&)»`t`t«(&c&)»
Нем. „лапки“%A_Tab%Alt+0132/0147
„(&c&)“`t`t„(&c&)“
“Англ. двойные”%A_Tab%Alt+0147/0148
“(&c&)”`t`t“(&c&)”
‘Англ. одинарные’%A_Tab%Alt+0145/0146
‘(&c&)’`t`t‘(&c&)’
&Bold
<b>(&c&)</b>`t`t[b](&c&)[/b]
&Italic
<i>(&c&)</i>`t`t[i](&c&)[/i]
) ; и прочая, и прочая, и прочая...





^sc052::        ;Ctrl + Num 0
QLinesMenu:
   ; Send Ctrl+C, to copy selection to clipboard
   Send, {CTRL DOWN}{sc02E}{CTRL UP}  ;c
   Sleep 200   ; Wait to be sure there is something copied
   If ErrorLevel
   {
      CoordMode, ToolTip, Screen
      ToolTip, !! Sorry, cannot copy the selection !!,0,0
      Sleep, 3000
      tooltip
      Return
   }
   ; Create a menu
   CreateMenu("mHTML", menuHTMLify, "HTMLify")
   ; And show it
   Menu mHTML, Show
Return

HTMLify:
   ; Go here when choosing a menu item
   RunMenuItem(menuHTMLify, A_ThisMenuItemPos)
Return

CreateMenu(_menuName, _menuDef, _menuLabel)
{
   Loop Parse, _menuDef, `n
   {
      If (Mod(A_Index, 2) = 1) ; Odd
      {
         Menu %_menuName%, Add, %A_LoopField%, %_menuLabel%
      }
   }
}

RunMenuItem(_menuDef, _index)
{
   Loop Parse, _menuDef, `n
   {
      If (_index * 2 = A_Index)
      {

         If GetKeyState("Ctrl")
         {
            html := A_LoopField
            html := RegExReplace(html, ".*\t\t", "$2")
            StringReplace html, html, (&c&), %Clipboard%, All
            Clipboard := html
            Send, {Ctrl Down}{sc02F}{Ctrl Up}  ;v
            Break
            Return
         }

         ; Get HTML
         html := A_LoopField
         html := RegExReplace(html, "\t.*", "$2")
         ; Substitute special tag with clipboard content
         StringReplace html, html, (&c&), %Clipboard%, All
         ; Update the clipboard
         Clipboard := html
         Send, {Ctrl Down}{sc02F}{Ctrl Up}  ;v
         Break
      }
   }
}

2 (изменено: monsoon, 2015-12-29 16:06:11)

Re: AHK: Быстрое обрамление текста

Скрипт напомнил утилиту SpecChar, которой раньше пользовался. Её минусы: нельзя было сделать обрамление текста тегами и у меня почему-то не вставлялись длинные составные теги, например, quote
Cкрипт DD хорош, но не устраивало, что он делает замену в буфере. Если текст не выделен и буфер не пуст, для меня лучше было бы вставлять теги. Ну и еще в SpecChar было несколько столбцов.

Попробовал переделать под себя. Вот так пока выглядит окно:
http://s1.bild.me/bilder/030315/4997178tegs.JPG

Скрипт:

#SingleInstance force

^sc052::      ;Ctrl + Num 0

menuHTMLify =
(
«Франц. елочки»%A_Tab%Alt+0171/0187
«(&c&)»`t`t&laquo;(&c&)&raquo;
„Нем. лапки“%A_Tab%Alt+0132/0147
„(&c&)“`t`t&bdquo;(&c&)&ldquo;
“Англ. двойные”%A_Tab%Alt+0147/0148
“(&c&)”`t`t&ldquo;(&c&)&rdquo;
‘Англ. одинарные’%A_Tab%Alt+0145/0146
‘(&c&)’`t`t&lsquo;(&c&)&rsquo;
Ударение%A_Tab%́
́
Среднее тире%A_Tab%–
–
Длинное тире%A_Tab%—
—
Параграф%A_Tab%§   Alt+21
§
Градус%A_Tab%°
°
Символ пробела%A_Tab%(нижняя скобка)
␣
&Bold
[b](&c&)[/b]`t`t<b>(&c&)</b>
&Italic
[i](&c&)[/i]`t`t<i>(&c&)</i>
<p>
<p>(&c&)</p>
<br>
<br>
<strong>
<strong>(&c&)</strong>
<pre>
<pre>(&c&)</pre>
<blockquote>
<blockquote>(&c&)</blockquote>
©
©
∞
∞
≈
≈
±
±
≠
≠
≤ / ≥
≤`t`t≥
×
×
÷
÷
√
√
∑
∑
) ; и прочая, и прочая, и прочая...

MenuBreakItem01:=10
MenuBreakItem02:=21

   ControlGetFocus, CurControl, A

   VarSetCapacity(SelStart, 4), VarSetCapacity(SelEnd, 4)
   SendMessage, 0xB0, &SelStart, &SelEnd, %CurControl%, A  ;EM_GETSEL

   SelStart := NumGet(SelStart), SelEnd := NumGet(SelEnd)

   ClipSave:=ClipboardAll     ; Save original clipboard 
   Clipboard =                ;   

   ; Send Ctrl+C, to copy selection to clipboard
   Send, {CTRL DOWN}{sc02E}{CTRL UP}  ;c
   Sleep 200   ; Wait to be sure there is something copied

;  Create a menu
   CreateMenu("mHTML", menuHTMLify, "HTMLify")

;  Create menu column
   MenuHandle := GetMenuHandle("mHTML")
   VarSetCapacity(mii,48,0),NumPut(48,mii)
   NumPut(0x100,mii,4) ; fMask = MIIM_FTYPE
   NumPut(0x20,mii,8)  ; fType = MFT_MENUBARBREAK
   DllCall("SetMenuItemInfo","uint",MenuHandle,"uint",MenuBreakItem01,"uint",1,"uint",&mii)
   DllCall("SetMenuItemInfo","uint",MenuHandle,"uint",MenuBreakItem02,"uint",1,"uint",&mii)
   
   ; And show it
   Menu mHTML, Show

   Clipboard:=ClipSave
   
 ExitApp
Return

HTMLify:
   ; Go here when choosing a menu item
   RunMenuItem(menuHTMLify, A_ThisMenuItemPos)

   If (SelStart>0 and SelStart!=SelEnd)
   {
     PostMessage, 0xB1, SelStart, SelStart + StrLen(Clipboard), %CurControl%, A   ; EM_SETSEL
     PostMessage, 0xB7,,, %CurControl%, A    ; EM_SCROLLCARET  
   }
Return

CreateMenu(_menuName, _menuDef, _menuLabel)
{
   Loop Parse, _menuDef, `n
   {
      If (Mod(A_Index, 2) = 1) ; Odd
        Menu %_menuName%, Add, %A_LoopField%, %_menuLabel%
   }
}

RunMenuItem(_menuDef, _index)
{
   Loop Parse, _menuDef, `n
   {
      If (_index * 2 = A_Index)
      {
         If GetKeyState("Shift")
         {
            html := A_LoopField
            html := RegExReplace(html, ".*\t\t", "$2")

            pos := 0
            If Clipboard =
              pos := StrLen(html)-Instr(html,"(&c&)")-4

            StringReplace html, html, (&c&), %Clipboard%, All
            Clipboard := html

            Sleep 200   ; Wait to be sure there is something copied
            Send, {Ctrl Down}{sc02F}{Ctrl Up}  ;v
;           Send ^{vk56sc02F} ; Ctrl+V

            If (pos>0)
              Send, {Left %pos%}

            Break
            Return
         }

         ; Get HTML
         html := A_LoopField
         html := RegExReplace(html, "\t.*", "$2")

         pos := 0
         If Clipboard =
           pos := StrLen(html)-Instr(html,"(&c&)")-4

         ; Substitute special tag with clipboard content
         StringReplace html, html, (&c&), %Clipboard%, All
         ; Update the clipboard
         Clipboard := html

         Sleep 200   ; Wait to be sure there is something copied
         Send, {Ctrl Down}{sc02F}{Ctrl Up}  ;v
;         Send ^{vk56sc02F} ; Ctrl+V

         If (pos>0)
           Send, {Left %pos%}

         Break
      }
   }
}

GetMenuHandle(menu_name) ;from MenuIcons v2
{
    static   h_menuDummy
    ; v2.2: Check for !h_menuDummy instead of h_menuDummy="" in case init failed last time.
    If !h_menuDummy
    {
        Menu, menuDummy, Add
        Menu, menuDummy, DeleteAll

        Gui, 99:Menu, menuDummy
        ; v2.2: Use LastFound method instead of window title. [Thanks animeaime.]
        Gui, 99:+LastFound

        h_menuDummy := DllCall("GetMenu", "uint", WinExist())

        Gui, 99:Menu
        Gui, 99:Destroy
       
        ; v2.2: Return only after cleaning up. [Thanks animeaime.]
        if !h_menuDummy
            return 0
    }

    Menu, menuDummy, Add, :%menu_name%
    h_menu := DllCall( "GetSubMenu", "uint", h_menuDummy, "int", 0 )
    DllCall( "RemoveMenu", "uint", h_menuDummy, "uint", 0, "uint", 0x400 )
    Menu, menuDummy, Delete, :%menu_name%
   
    return h_menu
}

Итог отличается от указанного на скриншоте, т.к. пришлось поудалять примеры для тегов code, url, img  и quote и не помогало обрамление текста тегами pre.
Для составного пункта меню вызов осуществляется при зажатом Shift, а не Ctrl, уже не помню почему переделал.
Если текст не выделен, то при вставке кавычек или двойного тега (открывающего и закрывающего) курсор устанавливается после открывающей кавычки (тега).
Если текст выделен и выбран одиночный тег или символ, он заместит выделенное.
После обрамления выделенного текста тегами, он снова выделяется уже с ними для случая, когда текст нужно обрамить несколькими тегами.
Еще хорошо было бы вынести содержимое меню в отдельный ini-файл, чтобы было проще пользоваться другим и как было в SpecChar, в нем добавить спецсимволы, указывающие, откуда начинать новый столбец. Но в этом не силен. Не знаю, как оно вообще заработало. Может быть кто-то возьмется "допилить".

3 (изменено: monsoon, 2017-05-31 15:40:22)

Re: AHK: Быстрое обрамление текста

В win7 x64 меню не захотело разделяться на колонки.
На форуме autohotkey.com нашел ответ.
В скрипте нужно поменять блок:


;  Create menu column
   MenuHandle := GetMenuHandle("mHTML")
   VarSetCapacity(mii,48,0),NumPut(48,mii)
   NumPut(0x100,mii,4) ; fMask = MIIM_FTYPE
   NumPut(0x20,mii,8)  ; fType = MFT_MENUBARBREAK
   DllCall("SetMenuItemInfo","uint",MenuHandle,"uint",MenuBreakItem01,"uint",1,"uint",&mii)
   DllCall("SetMenuItemInfo","uint",MenuHandle,"uint",MenuBreakItem02,"uint",1,"uint",&mii)

на:


;  Create menu column
   MenuHandle := GetMenuHandle("mHTML")
   VarSetCapacity(mii, cb:=16+8*A_PtrSize, 0) ; A_PtrSize is used for 64-bit compatibility.
   NumPut(cb, mii, "uint")
   NumPut(0x100, mii, 4, "uint") ; fMask = MIIM_FTYPE
   NumPut(0x20, mii, 8, "uint") ; fType = MFT_MENUBARBREAK
   DllCall("SetMenuItemInfo","ptr",MenuHandle,"uint",MenuBreakItem01,"int",1,"ptr",&mii)
   DllCall("SetMenuItemInfo","ptr",MenuHandle,"uint",MenuBreakItem02,"int",1,"ptr",&mii)