Basic HTML operations in Emacs - emacs

I am working with HTML in Emacs and I am looking for ways to make basics operations as:
convert list of string to HTML-list
one
two
three
to
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
add class to list of elements
<a></a>
<a></a>
<a></a>
to
<a class="one"></a>
<a class="one"></a>
<a class="one"></a>
Is there any extensions which can helps me?

I would do this with a macro:
Move to the first line, and type C-x (
Type the <li>, move to the end </li>, and move to the next line
End and repeat the macro on the remaining lines with C-x e e e e e...
This can easily be generalized to add classes to your <a> tags, and many other things.

You should take a look at zencoding , it's pretty useful. Here's a youtube video showing it with yasnippet, showing some functionality like what you want.

You can add class to list of elements using command M-x replace-string.

Here is an Emacs Lisp function which performs the first task (operates on selected text):
(defun my-make-list (start end)
(interactive "r")
(insert "<ul>\n")
(mapcar '(lambda (line) (insert (concat " <li>" line "</li>\n")))
(split-string (buffer-substring start end) "\n"))
(insert "</ul>")
(delete-region start end))
In the second case I would just use search/replace.

Related

Close HTML tags as soon as one opens them

I'd like the corresponding, closing HTML tag to be automatically inserted whenever I open one.
So if I type
<div>
I should get
<div></div>
Without having to call to sgml-close-tag myself.
How to achieve this?
Rather than calling a hook function after every single key-stroke, it makes sense to only call it after a > was typed. This can be achieved by rebinding the > character in the keymap that sgml-mode uses.
In addition, sgml-close-tag shouldn't get called if the tag is already closed. Therefore, the following code adds a simple regexp check for that:
(defun my-sgml-insert-gt ()
"Inserts a `>' character and calls
`my-sgml-close-tag-if-necessary', leaving point where it is."
(interactive)
(insert ">")
(save-excursion (my-sgml-close-tag-if-necessary)))
(defun my-sgml-close-tag-if-necessary ()
"Calls sgml-close-tag if the tag immediately before point is
an opening tag that is not followed by a matching closing tag."
(when (looking-back "<\\s-*\\([^</> \t\r\n]+\\)[^</>]*>")
(let ((tag (match-string 1)))
(unless (and (not (sgml-unclosed-tag-p tag))
(looking-at (concat "\\s-*<\\s-*/\\s-*" tag "\\s-*>")))
(sgml-close-tag)))))
(eval-after-load "sgml-mode"
'(define-key sgml-mode-map ">" 'my-sgml-insert-gt))
If you like paredit (and if you're an emacs user, chances are you do), you may be interested in tagedit, an emacs package written by Magnar Sveen that provides paredit-like features for editing html.
The library is here: https://github.com/magnars/tagedit, and can be installed through Melpa/Marmalade (package-install tagedit).
If you enable the experimental features (tagedit-add-experimental-features), then it will automatically close tags for you and keep the corresponding closing tag text matching the opening tag text. That's on top of being able to splice, slurp, barf and all the other crazy things that paredit lets you do when working with balanced expressions...I think it's great!
I'm using yasnippet for this purpose.
To type shortcuts this answer, like <kbd>C-o</kbd>, I have the following snippet:
# -*- mode: snippet -*-
# name: kbd
# key: kbd
# --
<kbd>$0</kbd>
So I type kbdC-o and it get's expanded to <kbd></kbd> with cursor
right in the middle. You can have the same behavior for div.
You may eval this on your sgml-buffer or add ii to your sgml-hook:
(add-hook 'post-self-insert-hook
(lambda () (and (eq (char-before) ?>) (sgml-close-tag))) nil t)
Whenever you insert a ">", the function sgml-close-tag will be run for you

Interactively enter headline under which to place an entry using capture

Using capture templates like the one below, I can add entries to different headlines in a file. How can I manually enter a headline during capture, instead of setting up each headline to a key in the .emacs file like I am now doing?
(setq org-capture-templates
'(
("l" "Log" entry
(file+headline "c:/Org/log.org" "Log")
"\n\n** %?\n<%<%Y-%m-%d %a %T>>"
:empty-lines 1))
It looks like, in newer versions of org at least, that custom functions can be used in capture templates to do this.
Instead of:
entry
(file+headline "~/Work/work.org" "Refile")
You can use:
entry
(file+function "~/Work/work.org" function-finding-location)
Where 'function-finding-location' is a custom function you have written yourself, which could easily prompt you for a headline.
Or, you can go even farther, and define a custom function which will prompt for both file name and headline name (or anything else you can dream up):
entry
(function function-finding-location)
I don't really know enough elisp to write these functions myself, but this looks like the place to start. It'd be nice if someone else could offer up some code. The relevant documentation is here:
http://orgmode.org/manual/Template-elements.html
I wrote a function to be used with file+function which will prompt for a location on capture.
It uses the internal prompting function of org-refile so we get completions of headings in the prompt (with maxlevels overridden to 9). When the user enters an unknown heading, it creates it at the end of the file.
(defun org-ask-location ()
(let* ((org-refile-targets '((nil :maxlevel . 9)))
(hd (condition-case nil
(car (org-refile-get-location nil nil t t))
(error (car org-refile-history)))))
(goto-char (point-min))
(outline-next-heading)
(if (re-search-forward
(format org-complex-heading-regexp-format (regexp-quote hd))
nil t)
(goto-char (point-at-bol))
(goto-char (point-max))
(or (bolp) (insert "\n"))
(insert "* " hd "\n")))
(end-of-line))
In your case, you use it like this:
(setq org-capture-templates
'(("l" "Log" entry
(file+function "c:/Org/log.org" org-ask-location)
"\n\n** %?\n<%<%Y-%m-%d %a %T>>"
:empty-lines 1))
I don't believe you can have it prompt for the headline on capture. You can however refile from within the capture window which should result in the desired behaviour.
I would define a catch-all target headline/file so that if you forget you will always collect them in the same location and then just have to refile them once created. If you also set a category/tag on this headline you will be able to easily see the misfiled capture entry and refile it as desired. (Example below)
Then instead of finishing with C-c C-c choose to refile with C-c C-w and you will be asked to select the headline you want to send the new entry to.
The capture template I use for this catch all is as follows (adapted from Bernt Hansen's capture settings)
("i"
"Incidents"
entry
(file+headline "~/Work/work.org" "Refile")
"* TODO %^{Ticket} - %^{User}\nSCHEDULED: %^t DEADLINE: %^t\n:PROPERTIES:
\n:DATE: %^U\n:END:\n%^{MANAGER}p%^{HOSTNAME}p%^{LOCATION}p%^{TEL}p\n%c"
:empty-lines 1 :clock-in t :clock-resume t)
(Line breaks are added to avoid scrolling when reading here)
The heading is configured as follows
* Refile :refile:
:PROPERTIES:
:CATEGORY: Unsorted
:END:
With this I end up with all non-refiled tasks showing up as
Unsorted: Deadline: TODO <Headline> :refile::
I currently tend to use tags as reference if I'm waiting for coworkers/managers to deal with the ticket, or to remind me to speak to them about it when I see them so the tag at the end stands out clearly, as does Unsorted if I'm trying to remember what the issue is (since I simply have a case number and user name showing, details within the entry).
while capturing a note, after finishing writeup press C-u C-c C-w to refile under desired new headline.
you also need to set this variable
(setq org-refile-allow-creating-parent-nodes (quote confirm))
you can set it to t instead of confirm. But I like it be confirm because I dont often refile to new targets

How to mark the text between the parentheses in Emacs?

Any such function or elisp script? I want the equivalent function as vi" sequence in vim.
Try the key sequence C-M-u C-M-SPC (i.e., while holding the Control and Meta keys, press u and Space in sequence), which executes the commands backward-up-sexp and mark-sexp.
Edit:
I made a mistake: backward-up-sexp doesn't exist in standard Emacs. I wrote it exactly because of the problem mentioned in lkahtz's comment, that the existing function backward-up-list won't work when point is between double quotes.
(defun backward-up-sexp (arg)
(interactive "p")
(let ((ppss (syntax-ppss)))
(cond ((elt ppss 3)
(goto-char (elt ppss 8))
(backward-up-sexp (1- arg)))
((backward-up-list arg)))))
(global-set-key [remap backward-up-list] 'backward-up-sexp)
expand-region (which is bound to C-=) works great.
Xah Lee has an emacs-lisp function which achieves this called xah-select-text-in-quote. It is available from his website:
Select text between the nearest left and right delimiters.
Delimiters here includes the following chars: \"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕().
This command does not properly deal with nested brackets.

(re)number numbered lists in emacs (muse)

suppose I have a text list in emacs like this:
a
b
c
...
d
Is there a way to assign numbers to those items in Emacs, by selecting the region? End results should look like:
1. a
2. b
3. c
j. ...
n. d
Thanks.
The way I do this, which may not be optimal, is to use regex search and replace. This, of course, requires that you be able to define a regex to match the start of the lines you want numbers on. Taking your example, I'd use a search regex like this:
\([a-z]\)
note the capturing brackets, we'll need that first letter soon. And a replace regex like this:
\#. \1
where:
\# is a special form which is replaced, by Emacs, by the right number (though see the warning below);
. writes a stop; and
\1 writes a space and the captured group.
WARNING: Emacs will number your items 0, 1, 2, .... Until someone posts to tell us how to start at 1, I always insert a dummy 0th element before the edit, then delete it.
You can use the Emacs Keyboard Macro Counter.
Put the cursor one line ABOVE your list.
Start a macro: F3
Insert the counter value: C-x C-k C-i. A 0 will appear
Insert the DOT and a space: .
Move the cursor to the next line
Stop the macro: F4
Select your list
M-x apply-macro-to-region-lines
You can delete the 0 you added on the top and enjoy :)
NOTE: This will create a numbered list. It will not use letters.
A much simpler way is to use the CUA library's advanced rectangle editing commands. CUA is included in Emacs (at least 23.1, I think it's in earlier versions as well), so there isn't any new code to get.
You can use cua-set-rectangle-mark (bound to C-Return by default) to start a rectangle, and then use cua-sequence-rectangle to insert increasing values. It also gives you control over the format and starting value, so there is a lot of flexibility.
As an aside, CUA is primarily designed to make Emacs operate more like standard text editors (with C-c for copy, C-v for paste, etc), but it also includes some unrelated niceties, like rectangle editing. Don't ask me why :). If you want to use the rectangle editing without enabling the CUA keybindings (which is what I do), set cua-enable-cua-keys to nil, which can be done via customize.
(defun number-region (start end)
(interactive "r")
(let* ((count 1)
(indent-region-function (lambda (start end)
(save-excursion
(setq end (copy-marker end))
(goto-char start)
(while (< (point) end)
(or (and (bolp) (eolp))
(insert (format "%d. " count))
(setq count (1+ count)))
(forward-line 1))
(move-marker end nil)))))
(indent-region start end)))
Here's some elisp code to do it; would be easy to customize if you like tinkering.
This will number the current region (unless it is already numbered), and also the last line binds to the M-n keys. You could use a function key "[F6]" as needed.
Modified to take a format string to use. The default is 1. but you could do something like %d) to get a bracket instead of a . and so on.
(defun number-region(fmt)
(interactive "sFormat : ")
(if (or (null fmt) (= 0 (length fmt)))
(setf fmt "%d. "))
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(goto-char (point-min))
(let ((num 1))
(while (> (point-max) (point))
(if (null (number-at-point))
(insert (format fmt num)))
(incf num)
(forward-line))))))
(global-set-key "\M-n" 'number-region)
Not a direct answer to your question, but if you find yourself manipulating numbered lists frequently, you may want to look into org-mode. In particular, the section on plain lists.

By Emacs, how to join two lines into one?

I am new to Emacs. I have googled this but no good answer there. One of them is
Ctrl-n Ctrl-a Backspace
This works but is stupid. Is there a quick and simple way to join a block of lines into a single line?
Actually, I can use Esc-q to auto-fill a paragraph now, but how could I get it to revert without UNDO?
Place point anywhere on the last line of the group of lines that need joining and call
M-^
repeatedly until all the lines are merged.
Note: It leaves one space between all of the now joined lines.
M-x join-line will join two lines. Just bind it to a convenient keystroke.
Multiple Cursors combined with M-^ will collapse all selected lines into one with all extraneous white-space removed.
For example to select an entire buffer, invoke multiple cursors mode, collapse into one line, and then disable multiple cursors mode:
C-x h
M-x mc/edit-lines
M-^
C-g
The Emacs conventional name for "join" is "fill". Yes, you can join
two lines with M-^ -- and that's handy -- but more generally you'll
want to join n lines. For this, see the fill* commands, such as
fill-region, fill-paragraph, etc.
See this for more info
on selecting things which can then be filled.
Also, you can join multiple lines with M-^ by selecting those lines first. (Note that the universal argument does not work with this.)
Just replace newlines with nothing.
I like the way Sublime text Join line with Command J so I do it this way:
(defun join-lines (arg)
(interactive "p")
(end-of-line)
(delete-char 1)
(delete-horizontal-space)
(insert " "))
You could define a new command for this, temporarily adjusting the fill width before using the the Esc-q command:
;; -- define a new command to join multiple lines together --
(defun join-lines () (interactive)
(setq fill-column 100000)
(fill-paragraph nil)
(setq fill-column 78)
)
Obviously this only works, if your paragraph has less than 100000 characters.
I use the following function and bind it to 'M-J'.
(defun concat-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space))
If you prefer to keep your cursor position, you can use save-excursion.
The most simplest way ever:
Select paragraph/lines by M-h or C-SPC
Press M-q
Witness the Emagics (Emacs Magic)!!
Because join-line will left one space between two lines, also it only support join two lines. In case of you want to join plenty of lines without one space left, you can use "search-replace" mode to solve, as follows:
C-%
Query: input C-q C-j Enter
Replace: Enter
Run the replacement. Enter
Done.
Two ways come to mind:
Once you think of it, the most obvious (or at least easiest to remember) way is to use M-q format-paragraph with a long line length C-x-f 1000.
There is also a built-in tool M-^ join-line. More usefully, if you select a region then it will combine them all into one line.
"how could I get it to revert without UNDO?":
(defun toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
(global-set-key (kbd "M-q") 'toggle-fill-paragraph)
From EmacsWiki: Unfill Paragraph
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
A basic join of 2 lines:
(delete-indentation)
I like to line below to be joined to the current without moving the cursor:
("C-j" .
(lambda (iPoint)
"Join next line onto current line"
(interactive "d")
(next-line)
(delete-indentation)
(goto-char iPoint)))
This one behaves like in vscode. So it add space only if join line consisted something else than whitespace. And I bind it to alt+shift+j.
Shorter version based on crux-top-join-line:
(global-set-key (kbd "M-J") (lambda () (interactive) (delete-indentation 1)))
Longer version based on https://stackoverflow.com/a/33005183/588759.
;; https://stackoverflow.com/questions/1072662/by-emacs-how-to-join-two-lines-into-one/68685485#68685485
(defun join-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space)
(unless (looking-at-p "\n") (insert " ")))
(global-set-key (kbd "M-J") 'join-lines)