orgmode region to table - emacs

I have a region:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
I would like to create org-table of the above region:
|Items | Quantity| Amount|
----------------|------------------
|"Item A" | 423 | 63 |
|"Item A and C" | 27 | 169 |
|"Item D" | 6 | 199 |
The current suggestion is to select the region and use C-c | to create the table but this creates a table based on spaces between the elements. It is not able to group the items column. Is there a way I can group

You can write your own Emacs Lisp function which will convert all the white-chars (not only spaces) between the two sexp and replace them with , in the currently active region.
(defun my/convert-region ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(goto-char (point-min))
(widen)))
I checked this on such active region:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
After running M-x my/convert-region it was changed to:
Items,Quantity,Amount
"Item A",423,63
"Item B and C",27,169
"Item D ",6,199
You can add this function to your config file and bind it to some keys.
If you want this function to convert this region to the org-table in the same function just add org-table-convert-region call.
(defun my/convert-region-to-org-table ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(org-table-convert-region (point-min) (point-max) '(4))
(goto-char (point-min))
(widen)))
For the same input:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
I got the following result:
| Items | Quantity | Amount |
| Item A | 423 | 63 |
| Item B and C | 27 | 169 |
| Item D | 6 | 199 |
Unfortunately the quotation marks are being removed by org-mode during the conversion.
(defun my/convert-region-to-org-table-with-header ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(org-table-convert-region (point-min) (point-max) '(4))
(goto-char (point-min))
(org-ctrl-c-minus)
(widen)))
Then the output will look like this:
| Items | Quantity | Amount |
|--------------+----------+--------|
| Item A | 423 | 63 |
| Item B and C | 27 | 169 |
| Item D | 6 | 199 |
I can explain how the code works if anyone is interested. This answer is already pretty long so I am not going to do that now when not sure if it will be useful for anyone.
Hope that helps.

In these cases i normally create an emacs macro:
position the cursor on the second line (As your first line does not contain the quotes, it will not work there) of your table.
Press f3 and then:
C-a
Then press the pipe: "|"
press "delete" to remove the first double quote
search for the next double quote C-s "
remove the double quote and add another pipe sign
move one word further with C-right
add another pipe
C-e
add another pipe
move one line down with the cursor
press f4 to close the marco
When you now press f4 it should execute the same again.
If everything went fine, then you can execute the command easily hundreds of times through C- any number you want and "f4".
After that is done, you can simply also add pipes in the first line once.
Now pressing "tab" inside the org-table will align everything.
Hope that helps.

Related

How to run sum of a buffer?

So, from my log file, I processed some string and finally got this result in, let's say buffer name "1"
12
23
34
45
How can I get a sum of a given buffer?
(defun sum-of-buffer (buf)
(interactive "bBuffer Name: ")
....
(message "%i" sum))
Or is there a convenient function combination?
How about using calc -- select the region in the shape of a rectangle -- and type: C-u C-x * :
Alternatively, how about?:
(let ((sum 0))
(save-excursion
(goto-char (point-min))
(while (re-search-forward "[0-9]*\\.?[0-9]+" nil t)
(setq sum (+ sum (string-to-number (match-string 0))))))
sum)
If you're on a Unix machine, C-x h M-| and then awk '{s+=$1} END {print s}'.

Replacing word in inactive buffer

If I have two buffers open (side-by-side) and I move from one window to another, can I replace previously selected word in the first (now inactive) window with the one that is under cursor in active window?
_ is cursor
_______________
| foo | _bar |
| | |
| | |
| | |
|_______|_______|
is there an internal command that can quickly let me replace foo with bar?
No internal commands, but this is Emacs:
(defun replace-word-other-window ()
(interactive)
(let ((sym (thing-at-point 'symbol))
bnd)
(other-window 1)
(if (setq bnd (bounds-of-thing-at-point 'symbol))
(progn
(delete-region (car bnd) (cdr bnd))
(insert sym))
(message "no symbol at point in other window"))
(other-window -1)))
update: advanced version
(defun region-or-symbol-bounds ()
(if (region-active-p)
(cons (region-beginning)
(region-end))
(bounds-of-thing-at-point 'symbol)))
(defun replace-word-other-window ()
(interactive)
(let* ((bnd-1 (region-or-symbol-bounds))
(str-1 (buffer-substring-no-properties
(car bnd-1)
(cdr bnd-1)))
(bnd-2 (progn
(other-window 1)
(region-or-symbol-bounds))))
(if bnd-2
(progn
(delete-region (car bnd-2) (cdr bnd-2))
(insert str-1))
(message "no region or symbol at point in other window"))
(other-window -1)))

macro for deleting selected rows from org table

I have some org table with 5 columns and 100 rows.
I would like to delete all those rows with field $3="away".
Below is the function that should do the following. Unfortunately I do not know how to convert org table that is created with (org-table-to-lisp), back to text table into my buffer.
(defun org-table-tests ()
"acts on balance table itself"
(interactive)
(save-excursion
(unless (org-table-p)
(error
"You are not in an org-table."))
(goto-char (org-table-begin))
(let (out-tbl
(tbl-list (org-table-to-lisp)))
(while
(let ((row-list (car tbl-list)))
(cond ((and
(listp row-list)
;; do not copy "away" (3rd column) lines containing folliwng:
(string-match "away" (nth 2 row-list)))
;; just skip copying to new table
)
(t (setq out-tbl (cons row-list out-tbl))))
(setq tbl-list (cdr tbl-list))))
;;(orgtbl-to-generic out-tbl) <---------- QUESTION: which function to use to convert back to table in text format.
)))
... or maybe there is a better way for doing such tasks with orgtbl mode?
Since your main question was answered, here's now a solution that doesn't rely on converting to lisp and back :
(defun org-table-tests ()
(interactive)
(save-excursion
(unless (org-table-p)
(error "You are not in an org-table."))
(goto-char (org-table-begin))
(while (org-table-p)
(if (string-match "away" (save-excursion (org-table-get-field 3)))
(delete-region (point) (progn (forward-line) (point)))
(forward-line)))))
Have a look at org-listtable-to-string. It's the reverse of org-table-to-lisp.
Also have a look at this screencast to see how
I've found the solution in under a minute (just grepped for "to table" in org's code base, basically).
If you just want to remove row where $3=="away", following commands are useful. But I don't know why it works.
ESC M-<
M-x flush-lines
RET
^[|][^|]*[|][^|
]*[|] away [|]
RET
Input:
| 1 | 2 | 3 | 4 | 5 |
|------+------+------+------+------|
| away | 12 | 13 | 14 | away |
| 21 | 22 | away | 24 | 25 |
| 31 | away | 33 | away | 35 |
Output:
| 1 | 2 | 3 | 4 | 5 |
|------+------+------+------+------|
| away | 12 | 13 | 14 | away |
| 31 | away | 33 | away | 35 |

a custom comment box on emacs

What would an Emacs macro look like which turns the following line:
# abc def
into:
# +-------------+
# | abc def |
# +-------------+
? The macro need not be general at all: It can hard code the box specs (i.e. 3 spaces before and after the comment, the frame characters (|, +, - ), and assume that the comment is a one-liner. It should, however, use whatever comment character is set for the current mode, and get the box length correct.
I'd also appreciate if you knew of an existing package which does this.
Thanks!
This does what I think you want:
(defun box-comment-region (beg end)
"do some fancy commenting"
(interactive "r")
(save-restriction
(narrow-to-region beg end)
(comment-region beg end -1) ; first, uncomment
(string-rectangle (point-min)
(progn (goto-char (point-max)) (line-beginning-position))
" | ")
(goto-char (point-min))
(let ((max-len 0))
(while (< (point) (point-max))
(end-of-line)
(setq max-len (max max-len (current-column)))
(forward-line 1))
(previous-line)
(end-of-line)
(insert (make-string (- max-len (current-column)) ?\ ))
(goto-char (point-min))
(end-of-line)
(insert (make-string (- max-len (current-column)) ?\ ))
(end-of-line)
(let ((top (point)))
(goto-char (point-max))
(previous-line)
(end-of-line)
(string-rectangle top (point) " | "))
(let ((line-seg (concat " +" (make-string (- max-len 2) ?-) "+ \n")))
(goto-char (point-max))
(insert line-seg)
(goto-char (point-min))
(insert line-seg)))
(comment-region (point-min) (point-max))))
newcomment has a function called comment-box, which produces a box comment consisting of the comment characters, i.e.:
###########
# abc def #
###########
or
/***********/
/* abc def */
/***********/
depending on the mode. The only configurability it has is the number of characters to use for the box; for example in Lisp modes you end up with:
;;;;;;;;;;;;;
;; abc def ;;
;;;;;;;;;;;;;
The comment-region-default function should give you some idea of how to do comments. newcomment's comment styles aren't sufficiently flexible to implement what you want, so I think it'd be easiest to simply draw the box then add a regular (single or multiline, in languages where there is difference) comment to the region using the existing newcomment machinery.
There is a feature called picture-mode, which might do something like that.
M-x picture-mode
rebox2 is the most comprehensive emacs box drawing extension.
The function
M-x comment-box
available as of Emacs 24.4 does this using point and mark as one would expect.

Org-Mode table to s-expressions

I would like to export from Org-Mode tables to s-expressions.
| first | second | thrid |
|--------+--------+--------|
| value1 | value2 | value3 |
| value4 | value5 | value6 |
Would turn into:
((:FIRST "value1" :SECOND "value2" :THIRD "value3")
(:FIRST "value4" :SECOND "value5" :THIRD "value6"))
I plan on writing such a setup if it doesn't exist yet but figured I'd tap into the stackoverflow before I start reinventing the wheel.
This does the trick. It has minimal error checking.
The interface to use is either the programmatic interface:
(org-table-to-sexp <location-of-beginning-of-table> <location-of-end-of-table>)
In which case it'll return the sexp you requested.
If you wanted an interactive usage, you can call the following command to operate on the table in the region. So, set the mark at the beginning of the table, move to the end, and type:
M-x insert-org-table-to-sexp
That will insert the desired sexp immediately after the table in the current buffer.
Here is the code:
(defun org-table-to-sexp-parse-line ()
"Helper, returns the current line as a list of strings"
(save-excursion
(save-match-data
(let ((result nil)
(end-of-line (save-excursion (end-of-line) (point))))
(beginning-of-line)
(while (re-search-forward "\\([^|]*\\)|" end-of-line t)
(let ((match (mapconcat 'identity (split-string (match-string-no-properties 1)) " ")))
(if (< 0 (length match))
;; really want to strip spaces from front and back
(push match result))))
(reverse result)))))
(require 'cl)
(defun org-table-to-sexp (b e)
"Parse an org-mode table to sexp"
(save-excursion
(save-match-data
(goto-char b)
(let ((headers (mapcar
(lambda (str)
(make-symbol (concat ":" (upcase str))))
(org-table-to-sexp-parse-line)))
(sexp nil))
(forward-line 1) ;skip |--+--+--| line
(while (< (point) e)
(forward-line 1)
(let ((line-result nil))
(mapcar* (lambda (h e)
(push h line-result)
(push e line-result))
headers
(org-table-to-sexp-parse-line))
(if line-result
(push (reverse line-result)
sexp))))
sexp))))
(defun insert-org-table-to-sexp (b e)
"Convert the table specified by the region and insert the sexp after the table"
(interactive "r")
(goto-char (max b e))
(print (org-table-to-sexp b e) (current-buffer)))