LQWiki trick cnee macro to launch preview from emacs

From LQWiki
Jump to navigation Jump to search
Edit your wiki articles in emacs and press F12 from there to launch a preview.

The core of it

If you like to edit wiki code in your favorite text editor you will find that manually copy-pasting from your text editor to the LQWiki edition box each time you want to get a preview can be very tedious and time consuming. This trick allows you to do all the required operations to get a preview by just pressing the F12 function key.

This is how you would do your wiki editing in emacs ( you can of course easily adapt the cnee macro to make it work with your favorite text editor ) :

  1. You insert the "#############" delimiters to seperate your edits by pressing Ctrl-Return (see define-key definitions).
  2. In the LQWiki edition page you do a Alt+, and Ctrl-a and then paste the whole text in emacs with a Ctrl-y.
  3. You do some editing...
  4. You press F12 to get a fast preview.
  5. If the preview is satisfactory you save, if not you go back to some emacs editing.
Ctrl-Alt-k copies the text being edited delimited by the "#############" string(s) to the X selection ( to the kill ring too ).

The cnee macro is highly dependent on your working environment since it reproduces low level X events. For instance it will reproduce keycodes, not symbol names, so if your keyboard layout is different from the us one you will probably have to adapt the macro to reflect that, especially for the "," key for instance. The keyboard shortcuts used in the macro will also have to be bound to the same software functions as those of the environment it was intended for.

You have to be a Alt-Tab away from your firefox window, which is displaying the LQWiki editing page of the corresponding article. Be carefull pasting two pages of text in the wrong window ( say a root xterm ) could be a bad idea...

The Firefox window is full screen with a screen resolution of 1280x1024. This can be important if you want the cnee macro to mouse-paste at the right position. Adapt the mouse coordinates in the cnee macro according to your screen configuration.

The F12 key is bound to the "cnee --replay" command thanks to the xbindkeys daemon.

When you press F12, the cnee macro simulates the pressure of the Ctrl-Alt-k key combination, followed by Alt-Tab to get to firefox, then clears the LQWiki edition box, pastes your emacs edited text in it, and launches the preview. This is very fast.

Please give feedback in case of problems.

Elisp code to put in your .emacs

elisp code to put in your .emacs
(progn
  (defun region-uuu-copy()
    (interactive)
    (let ((regbeg)(regend))
      (save-excursion
	(progn
	  (kill-new "")
	  (if (and (eq (marker-position (point-max-marker)) (marker-position (point-marker)))
		   (looking-at "^$"))
	      (previous-line-nomark 1))
	  (if (eq nil (search-backward-regexp "^#############$" nil t))
	      (progn
		(setq regbeg (point-min-marker)))
	    (progn
	      (next-line-nomark 1)
	      (beginning-of-line)
	      (setq regbeg (point-marker))))
	  (if (eq nil (search-forward-regexp "^#############$" nil t))
	      (setq regend (point-max-marker))
	    (progn
	      (beginning-of-line)
	      (setq regend (point-marker))))
	  (copy-region-as-kill regbeg regend)))))

  (defun region-uuu-insert-region-mark()
    (interactive)
    (if (and (looking-at "$") (not (looking-at "^$")))
	(newline))
    (insert "\#############\n"))

  (define-key global-map [C-return] 'region-uuu-insert-region-mark)
  (define-key global-map [(control meta ?k)] 'region-uuu-copy))

Install cnee

Install cnee
cd /usr/src/
wget http://ftp.gnu.org/gnu/xnee/Xnee-2.05.tar.gz
tar xzf Xnee-2.05.tar.gz
cd /usr/src/Xnee-2.05
./configure
make
make install

Set up xbindkeys

Set up xbindkeys
cat << EOF >> ~/.xbindkeysrc
#
"cnee --replay -f ~/etc/cnee/lq_wiki_preview.xnee_rec &"
F12
#
EOF
Start xbindkeys. If it is already runnning kill it so that it reads its configuration again.
pgrep 'xbindkeys' >&/dev/null && pkill xbindkeys; xbindkeys &

Set up the cnee macro

Set up the cnee macro

Create a directory to put the cnee macros : [ ! -e ~/etc/cnee ] && mkdir -p ~/etc/cnee

You can of course put the files in the place of your choice.
cat << EOF > ~/etc/cnee/lq_wiki_preview.xnee_rec
#Do a small pause
#
#Ctrl press+release
0,2,0,0,0,37,0,0900
0,3,0,0,0,37,0,1100
#
#Copy the text from emacs
#Ctrl-Alt-k
#
#Alt press
0,2,0,0,0,64,0,1350
#Ctrl press
0,2,0,0,0,37,0,1352
#k press
0,2,0,0,0,45,0,1460
#k release
0,3,0,0,0,45,0,1510
#Ctrl release
0,3,0,0,0,37,0,1520
#Alt release
0,3,0,0,0,64,0,1522
#
#Switch to firefox window
#Alt+Tab
#
#Alt press
0,2,0,0,0,64,0,1532
#Tab press
0,2,0,0,0,23,0,1534
#Tab release
0,3,0,0,0,23,0,1584
#Alt release
0,3,0,0,0,64,0,1594
#
#Go in the address bar
#Ctrl+l
#
#Ctrl press
0,2,0,0,0,37,0,1800
#l press
0,2,0,0,0,46,0,1810
#l release
0,3,0,0,0,46,0,1860
#Ctrl release
0,3,0,0,0,37,0,1870
#
#Get to the page body
#Tab+Tab+Tab
#
#Tab press+release
0,2,0,0,0,23,0,1890
0,3,0,0,0,23,0,1940
#Tab press+release
0,2,0,0,0,23,0,1960
0,3,0,0,0,23,0,2010
#Tab press+release
0,2,0,0,0,23,0,2030
0,3,0,0,0,23,0,2080
#
#Get to the end of page
#End
#
#End press+release
0,2,0,0,0,103,0,2100
0,3,0,0,0,103,0,2120
#
#Get in the textarea
#Alt+,
#
#Alt press
0,2,0,0,0,64,0,2140
#, press
#us--> "," = keycode 59, see xev for your keycode.
0,2,0,0,0,59,0,2150
#, release
0,3,0,0,0,59,0,2200
#Alt release
0,3,0,0,0,64,0,2210
#
#Select all the text
#Ctrl+Home
#Ctrl+Shift+End
#
#Ctrl_L press
0,2,0,0,0,37,0,2260
#Home press+release
0,2,0,0,0,97,0,2270
0,3,0,0,0,97,0,2310
#Shift_L press
0,2,0,0,0,50,0,2340
#End press+release
0,2,0,0,0,103,0,2360
0,3,0,0,0,103,0,2410
#Shift_L release
0,3,0,0,0,50,0,2420
#Ctrl_L release
0,3,0,0,0,37,0,2424
#
#Delete selected text
#Suppr.
#
#Suppr. press+release
0,2,0,0,0,107,0,2520
0,3,0,0,0,107,0,2570
#
#Move mouse over the text area
#
0,6,528,433,0,0,0,2640
#
#Paste X selection with
#middle button emulation
#
0,4,0,0,2,0,0,2690
0,5,0,0,2,0,0,2740
#
#Preview
#Alt+p
#
#Alt press
0,2,0,0,0,64,0,3000
#p press+release
0,2,0,0,0,33,0,3010
0,3,0,0,0,33,0,3060
#Alt release
0,3,0,0,0,64,0,3080
EOF

How was it recorded?

For your information here is the command that was run to record the initial macro :

beepf=/usr/share/sounds/KDE_Beep_Yo.wav && sleep 7s && play "$beepf" && cnee --record --time 0 --events-to-record 150 --delivered-event-range 2-6 -o ~/tmp/xnee.rec && play "$beepf"

Once done you can end the recording by moving your mouse around to get past the limit of events to record (150) and later delete those extra motion events (MotionNotify=6 in the second column). The last column has of course been edited for better timings, you could also try to change the speed rate by playing with the --speed-percent option ( buggy ? ).

Other elisp code : Navigate through your edits, kill a whole edit

Some other optional usefull elisp functions ( navigate through your edits, kill a whole edit ).
(defun delimited-sections-go-previous(delimiter)
  (interactive)
  (if (eq nil (search-backward-regexp delimiter nil t))
      (message "First region. Didn't move")
    (if (eq nil (search-backward-regexp delimiter nil t))
	(progn
	  (beginning-of-buffer)
	  (message "First region"))
      (next-line-nomark 1))))

(defun delimited-sections-go-next(delimiter)
  (interactive)
  (if (not (eq nil (search-forward-regexp delimiter nil t)))
      (forward-char-nomark 1)))

(defun region-uuu-go-previous()
  (interactive)
  (delimited-sections-go-previous  "^#############$"))

(defun region-uuu-go-next()
  (interactive)
  (delimited-sections-go-next  "^#############$"))

(defun region-uuu-kill()
"Kill the region delineated with marks into which point is"
  (interactive)
  (let ((regbeg)(regend))
    (save-excursion
      (progn
	(kill-new "")
	(if (and (eq (marker-position (point-max-marker)) (marker-position (point-marker)))
		 (looking-at "^$"))
	      (previous-line-nomark 1))
	(if (eq nil (search-backward-regexp "^#############$" nil t))
	    (progn
	      (setq regbeg (point-min-marker)))
	  (progn
	    (next-line-nomark 1)
	    (beginning-of-line)
	    (setq regbeg (point-marker))))
	(if (eq nil (search-forward-regexp "^#############$" nil t))
	    (setq regend (point-max-marker))
	  (progn
	    (beginning-of-line)
	    (next-line-nomark 1)
	    (setq regend (point-marker))))
	(kill-region regbeg regend)))))

(define-key global-map [(control ?x) (control meta ?k)] 'region-uuu-kill)
(define-key global-map [(control meta ?b)] 'region-uuu-go-previous)
(define-key global-map [(control meta ?f)] 'region-uuu-go-next)