Skip to content

Instantly share code, notes, and snippets.

@mojavelinux
Last active September 3, 2020 17:04
Show Gist options
  • Save mojavelinux/4736691 to your computer and use it in GitHub Desktop.
Save mojavelinux/4736691 to your computer and use it in GitHub Desktop.
Menu and key macros for AsciiDoc

Examples of custom macros for AsciiDoc

Path

path:/home/dallen/[]
path:/etc/my.cnf[]

Key

key:Enter[]
kbd:Enter[]
key:[Ctrl,S]
key:[Ctrl,Shift,T]
<Ctrl>S
<Ctrl><Shift>S

QUESTION: Does key:[Enter] make more sense for the single key form?

Button

btn:Save[]

QUESTION: Does btn:[Save] make more sense?

Menu

menu:File[]
menu:File[Close]
menu:File[New,Message]
File>New>Message
[macros]
# button:Next[] or btn:Next[]
(?su)(?<!\w)[\\]?(button|btn):(?P<target>\S+?)?\[\]=button
# key:Enter[] or key:[Ctrl+T] or key:[Ctrl+Shift+T]
(?su)(?<!\w)[\\]?(key|kbd):(?P<target>\S+?)?\[(?P<attrlist>.*?)\]=key
# <Ctrl>T or <Ctrl><Shift>T
(?su)(?<!\w)[\\]?&lt;(?P<accel>Ctrl|Alt|Shift)&gt;(&lt;(?P<accel2>Ctrl|Alt|Shift)&gt;)?(?P<key>F\d+|Up|Down|Left|Right|Page Up|Page Down|Space|Backspace|Tab|Esc|Home|End|\S)(?!\w)=key2
# menu:Search[] or menu:Search[Find Next] or menu:File[New,Message]
(?su)(?<!\w)[\\]?(?P<name>menu):(?P<target>\w+?( \w+)*?)?\[(?P<attrlist>.*?)\]=
# File>Close or "Events and Tasks">New>Task
(?su)(?<!\w)[\\]?((?P<menu>[^"\s]+)|"(?P<menualt>\w[\w\s]*?)")&gt;((?P<submenu>.+?)&gt;)?((?P<item>[^"\s]+)|"(?P<itemalt>\w[\w\s]*?)")(?!\w)=menu2
# path:/home/dallen/[]
# path:/etc/my.cnf[]
(?su)(?<!\w)[\\]?(?P<name>path):(?P<target>\S+?)\[(?P<attrlist>.*?)\]=
ifdef::basebackend-docbook[]
[key-inlinemacro]
# One key
{target#}{1%}<keycap>{target}</keycap>
# Two keys
{2#}{3%}{target%}<keycombo><keycap>{1}</keycap><keycap>{2}</keycap></keycombo>
# Three keys
{3#}{target%}<keycombo><keycap>{1}</keycap><keycap>{2}</keycap><keycap>{3}</keycap></keycombo>
[key2-inlinemacro]
{accel2%}<keycombo><keycap>{accel}</keycap><keycap>{key}</keycap></keycombo>
{accel2#}<keycombo><keycap>{accel}</keycap><keycap>{accel2}</keycap><keycap>{key}</keycap></keycombo>
[menu-inlinemacro]
# Menu
{target#}{1%}<guimenu>{target}</guimenu>
# Menu item
{target%}{1#}<guimenuitem>{1}</guimenuitem>
# First-level menu item
{1#}{2%}<menuchoice><guimenu>{target}</guimenu> <guimenuitem>{1}</guimenuitem></menuchoice>
# Second-level menu item
{2#}{3%}<menuchoice><guimenu>{target}</guimenu> <guisubmenu>{1}</guisubmenu> <guimenuitem>{2}</guimenuitem></menuchoice>
# Third-level menu item
{3#}<menuchoice><guimenu>{target}</guimenu> <guisubmenu>{1}</guisubmenu> <guisubmenu>{2}</guisubmenu> <guimenuitem>{3}</guimenuitem></menuchoice>
[menu2-inlinemacro]
# First-level menu item
{submenu%}<menuchoice><guimenu>{menu={menualt}}</guimenu> <guimenuitem>{item={itemalt}}</guimenuitem></menuchoice>
# Second-level menu item
{submenu#}<menuchoice><guimenu>{menu={menualt}}</guimenu> <guisubmenu>{submenu}</guisubmenu> <guimenuitem>{item={itemalt}}</guimenuitem></menuchoice>
[button-inlinemacro]
<guibutton>{target}</guibutton>
[path-inlinemacro]
{1%}<filename{target@^.*/$: class="directory":}>{eval:"{target}".rstrip('/')}</filename>
{1#}<filename class="{1}">{target}</filename>
endif::basebackend-docbook[]
ifdef::basebackend-html[]
[key-inlinemacro]
# One key
{target#}{1%}<span class="keycap">{target}</span>
# Two keys
{2#}{3%}{target%}<span class="keycombo"><span class="keycap">{1}</span>+<span class="keycap">{2}</span></span>
# Three keys
{3#}{target%}<span class="keycombo"><span class="keycap">{1}</span>+<span class="keycap">{2}</span>+<span class="keycap">{3}</span></span>
[key2-inlinemacro]
{accel2%}<span class="keycombo"><span class="keycap">{accel}</span>+<span class="keycap">{key}</span></span>
{accel2#}<span class="keycombo"><span class="keycap">{accel}</span>+<span class="keycap">{accel2}</span>+<span class="keycap">{key}</span></span>
[menu-inlinemacro]
{target#}{1%}<span class="guimenu">{target}</span>
{target%}{1#}<span class="guimenuitem">{1}</span>
{1#}{2%}<span class="menuchoice"><span class="guimenu">{target}</span>&#160;&#9656; <span class="guimenuitem">{1}</span></span>
{2#}{3%}<span class="menuchoice"><span class="guimenu">{target}</span>&#160;&#9656; <span class="guisubmenu">{1}</span>&#160;&#9656; <span class="guimenuitem">{2}</span></span>
{3#}<span class="menuchoice"><span class="guimenu">{target}</span>&#160;&#9656; <span class="guisubmenu">{1}</span>&#160;&#9656; <span class="guisubmenu">{2}</span>&#160;&#9656; <span class="guimenuitem">{3}</span></span>
[menu2-inlinemacro]
# First-level menu item
{submenu%}<span class="menuchoice"><span class="guimenu">{menu={menualt}}</span>&#160;&#9656; <span class="guimenuitem">{item={itemalt}}</span></span>
# Second-level menu item
{submenu#}<span class="menuchoice"><span class="guimenu">{menu={menualt}}</span>&#160;&#9656; <span class="guisubmenu">{submenu}</span>&#160;&#9656; <span class="guimenuitem">{item={itemalt}}</span></span>
[button-inlinemacro]
<b class="guibutton">{target}</b>
[path-inlinemacro]
<tt class="filename">{eval:"{target}".rstrip('/')}</tt>
endif::basebackend-html[]
= Path, Key, Button and Menu Macros
Dan Allen
== Path macro
Used for identifying file and directory references.
[cols="1l,2l,1", options="header"]
|===
|AsciiDoc source |Rendered source ({basebackend}) |As rendered
|path:/home/dallen/[]
|
ifdef::basebackend-docbook[<filename class="directory">/home/dallen</filename>]
ifdef::basebackend-html[<tt class="filename">/home/dallen</tt>]
|path:/home/dallen/[]
|path:/etc/my.cnf[]
|
ifdef::basebackend-docbook[<filename>/etc/my.cnf</filename>]
ifdef::basebackend-html[<tt class="filename">/etc/my.cnf</tt>]
|path:/etc/my.cnf[]
|===
== Key macro
Used for identifying key references and key combinations (shortcuts) on a keyboard.
[cols="1l,2l,1", options="header"]
|===
|AsciiDoc source |Rendered source ({basebackend}) |As rendered
|key:Enter[]
|
ifdef::basebackend-docbook[<keycap>Enter</keycap>]
ifdef::basebackend-html[]
<span class="keycap">Enter</span>
endif::basebackend-html[]
|key:Enter[]
|key:[Ctrl,Alt,F7]
<Ctrl><Alt>F7
|
ifdef::basebackend-html[]
<span class="keycombo"><
span class="keycap">Ctrl</span
>+<span class="keycap">Alt</span
>+<span class="keycap">F7</span
></span>
endif::basebackend-html[]
ifdef::basebackend-docbook[]
<keycombo>
<keycap>Ctrl</keycap>
<keycap>Alt</keycap>
<keycap>F7</keycap>
</keycombo>
endif::basebackend-docbook[]
|key:[Ctrl,Alt,F7] +
<Ctrl><Alt>F7
|===
== Button macro
Used for identifying UI button references.
[cols="1l,2l,1", options="header"]
|===
|AsciiDoc source |Rendered source ({basebackend}) |As rendered
|btn:Save[]
|
ifdef::basebackend-docbook[<guibutton>Save</guibutton>]
ifdef::basebackend-html[<b class="guibutton">Save</b>]
|btn:Save[]
|===
== Menu macro
Used for identifying UI menu references and menu selections.
[cols="1l,2l,1", options="header"]
|===
|AsciiDoc source |Rendered source ({basebackend}) |As rendered
|menu:Search[]
|
ifdef::basebackend-docbook[<guimenu>Enter</guimenu>]
ifdef::basebackend-html[<span class="guimenu">Search</span>]
|menu:Search[]
|menu:Search[Find Next]
Search>"Find Next"
|
ifdef::basebackend-html[]
<span class="menuchoice"><
span class="guimenu">Search</span
>&#160;&#9656; <span class="guimenuitem">Find Next</span
></span>
endif::basebackend-html[]
ifdef::basebackend-docbook[]
<menuchoice>
<guimenu>Search</guimenu>
<guimenuitem>Find Next</guimenuitem>
</menuchoice>
endif::basebackend-docbook[]
|menu:Search[Find Next] +
Search>"Find Next"
|menu:Main Menu[Utilities,Terminal]
"Main Menu">Utilities>Terminal
|
ifdef::basebackend-html[]
<span class="menuchoice"><
span class="guimenu">Main Menu</span
>&#160;&#9656; <span class="guisubmenu">Utilities</span
>&#160;&#9656; <span class="guimenuitem">Terminal</span
></span>
endif::basebackend-html[]
ifdef::basebackend-docbook[]
<menuchoice>
<guimenu>Main Menu</guimenu>
<guisubmenu>Utilities</guisubmenu>
<guimenuitem>Terminal</guimenuitem>
</menuchoice>
endif::basebackend-docbook[]
|menu:Main Menu[Utilities,Terminal] +
"Main Menu">Utilities>Terminal
|menu:[Save]
|
ifdef::basebackend-docbook[<guimenuitem>Save</guimenuitem>]
ifdef::basebackend-html[<span class="guimenuitem">Save</span>]
|menu:[Save]
|===
@bleathem
Copy link

QUESTION: Does btn:[Save] make more sense?

Yes. I have a use case where I want to generate: <guibutton>Set name to Alex</guibutton>

having the button text in the brackets allows would allow for spaces. (I think)

@bleathem
Copy link

So after playing around with the regexes a bit, you can have:

btn:Set name to Alex[]

I just feel that the following is more natural:

btn:[Set name to Alex]

@bleathem
Copy link

For guimenu's, this syntax:
File>Close or "Events and Tasks">New>Task

gave a lot of false positives with xml tags. I changed it to:

File->Close or "Events and Tasks"->New->Task

@bleathem
Copy link

I ended up going with a "+>" notation, as the "->" was gtting converted as a special character before the macro kicked in. I also had to make the regexp non greedy. It looks like:

# File+>Close or "Events and Tasks"+>New+>Task
(?su)(?<!\w)[\\]?((?P<menu>[^"\s]+?)|"(?P<menualt>\w[\w\s]*?)")\+\&gt;((?P<submenu>.+?)\+\&gt;)?((?P<item>[^"\s]+)|"(?P<itemalt>\w[\w\s]*?)")(?!\w)=menu

@aeisele
Copy link

aeisele commented Apr 23, 2013

What does it do, apart from wrapping the keys with spans? How do I get appropriate CSS to go with the keycap class?

@edusantana
Copy link

btn:Save[] is ugly. why not button:[Save]?

@xtaran
Copy link

xtaran commented Aug 28, 2015

Hi, under what license are those files? I assume "Expat" like Asciidoctor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment