In the Emacs manual the following is furnished as an example of a special entry in the Emacs Diary:
&%%(diary-float 11 4 4) American Thanksgiving
The 11 specifies the month, the first 4 specifies the day of the week (Thursday) and the second 4 the 4th Thursday of the month.
One can use t to indicate all months of the year, but how would one specify all Thursdays of the month? I have tried t and it does not work.
For example, let's say that every October I have to perform a duty, but not every day, only every Thursday. How would I capture that using a diary-float?
It's not possible to do this with diary-float, but as described in Sexp Entries in the Emacs manual, you can use an arbitrary Lisp expression in the diary file. This seems to work:
%%(let ((dayname (calendar-day-of-week date))
(month (car date)))
(and (= month 10) (= dayname 4))) It's a Thursday in October
Related
I am using Emacs and open calendar, now i would like to highlight weekend days with a light background color, i tried to google but have no solid solutions. anyone can help on this? thanks a lot!
Sorry I can't post pictures yet, hope i have put the question clearly.
Here you have some code that does that. You would need to change font-lock-doc-string-face to the face you want to use (or make a new one and configure it) if you don't like the one I used.
(defadvice calendar-generate-month
(after highlight-weekend-days (month year indent) activate)
"Highlight weekend days"
(dotimes (i 31)
(let ((date (list month (1+ i) year)))
(if (or (= (calendar-day-of-week date) 0)
(= (calendar-day-of-week date) 6))
(calendar-mark-visible-date date 'font-lock-doc-string-face)))))
Intro:
Based on the existing code for Emacs' diary-sunrise-sunset, I attempted to create two new functions diary-sunrise and diary-sunset.
My reasons for this are included below under the heading "XY-description".
I have code below which seems to work, except when I restart with a new Emacs. I can fix this by momentarily using the original built-in diary-sunrise-sunset. From then on, my functions perform beautifully.
In other words, I have to use the built-in %%(diary-sunrise-sunset) just a one time before my %%(diary-sunrise) and %%(diary-sunset) will work.
Question:
Can you help me fix my use of these functions so that I do not have to take the awkward step of first getting the built-in function called?
The lines of code that seem suspicious to me are the ones that go
;;;###diary-autoload
While I have some idea of the necessity of loading programs, I am not sure what's going on here, or if this is where the issue lies. (I've never seen that particular syntax.)
I have tried M-: (require 'solar) and M-: (require 'diary), but neither have worked (and just now calendar). I have tried putting my code both in my .emacs and in the built-in .../lisp/calendar/solar.el (and byte-recompiling), but neither have worked.
My functions:
(They are each slight modifications of solar-sunrise-sunset-string and diary-sunrise-sunset, which are both defined in .../lisp/calendar/solar.el).
Sunrise:
(defun solar-sunrise-string (date &optional nolocation)
"String of *local* time of sunrise and daylight on Gregorian DATE."
(let ((l (solar-sunrise-sunset date)))
(format
"%s (%s hours daylight)"
(if (car l)
(concat "Sunset " (apply 'solar-time-string (car l)))
"no sunset")
(nth 2 l)
)))
;; To be called from diary-list-sexp-entries, where DATE is bound.
;;;###diary-autoload
(defun diary-sunrise ()
"Local time of sunrise as a diary entry.
Accurate to a few seconds."
(or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup))
(solar-sunrise-string date))
Sunset:
(defun solar-sunset-string (date &optional nolocation)
"String of *local* time of sunset and daylight on Gregorian DATE."
(let ((l (solar-sunrise-sunset date)))
(format
"%s (%s hours daylight)"
(if (cadr l)
(concat "Sunset " (apply 'solar-time-string (cadr l)))
"no sunset")
(nth 2 l)
)))
;; To be called from diary-list-sexp-entries, where DATE is bound.
;;;###diary-autoload
(defun diary-sunset ()
"Local time of sunset as a diary entry.
Accurate to a few seconds."
(or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup))
(solar-sunset-string date))
XY description:
I am using Emacs' Org-mode, and just starting to use agenda views. I like the builtin diary-sunrise-sunset function, but wanted to make some minor tweaks to make it more to my liking.
Basically, Org-mode's agenda view will extract the first time it sees from the diary sexp %%(diary-sunrise-sunset), for instance
Sat, Apr 5, 2014
Sunrise 6:43am (PDT), sunset 7:42pm (PDT) at Springfield, OH (12:59 hours daylight)
and thus make an entry of
6:43am........ Sunrise (PDT), sunset 7:42pm (PDT) at Springfield, OH (12:59 hours daylight)
in the agenda view.
What I would like it to do is something more like,
6:43am........ Sunrise (PDT) (12:59 hours daylight)
8:00am........ ----------------
10:00am........ ----------------
12:00pm........ ----------------
2:00pm........ ----------------
4:00pm........ ----------------
5:51pm........ now - - - - - - - - - - - - - - - - - - - - - - - - -
6:00pm........ ----------------
7:42pm........ Sunset (PDT) (12:59 hours daylight)
Where the data is split into the two times, rather than all written only at the sunrise time.
Bonus:
a snippet so that C-c a d will give you a nice day agenda view:
(setq org-agenda-custom-commands
'(("d" "day's agenda"
agenda ""
(
(org-agenda-files '("/e/org/agendatest.org"))
(org-agenda-prefix-format "%t %s")
(org-agenda-span 'day)
(org-agenda-timegrid-use-ampm t)
)
)
))
In the last paragraph of my question (eighth paragraph?), I lied, (require 'solar) was the answer... I did not try it hard enough as it didn't respond to auto-completion.
The scenic route to the answer took me to these distractions:
Maintaining Emacs autoload files for user-installed elisp?
elisp - Where should I add autoload cookies in my Emacs Lisp package? Is there a definitive guide?
C-h i g (elisp) Autoload
a search through the lisp directory for any update-file-autoloads
I did some Edebugging wondering if anything I was using had an autoload cookie (not completely understanding it yet), but then noticed there was a (provide 'solar) at the end of solar.el, so then I figured (require 'solar) had to work. It did and that was that.
From the code in my question, I remove the autoload cookies (not sure if that's necessary), and add (require 'solar), and it works! Enjoy!
I'am trying now to create a racket program that displays an entered date (between 01.01.2000 and 31.12.2100) as a day.
best regards Keyane
The time-related libraries should be able to help here.
#lang racket
(require racket/date)
;; Given a day, month, and year, return the weekday
(define (day-month-year->weekday day month year)
(define local-secs (find-seconds 0
0
0
day
month
year
#t))
(define the-date (seconds->date local-secs))
(vector-ref #("sunday" "monday" "tuesday" "wednesday" "thursday"
"friday" "saturday")
(date-week-day the-date)))
For example, the date that I'm writing this in my area (November 17th, 2012) is a Saturday, and the day-month-year->weekday function supports this as well:
> (day-month-year->weekday 17 11 2012)
"saturday"
July 20, 1969 should be a Sunday:
> (day-month-year->weekday 20 7 1969)
"sunday"
Zeller's congruence is the algorithm that you will want to look at. It should be fairly straightforward to translate the algorithm from the math to Racket code.
Side note: when asking StackOverflow, it helps to ask a more specific question and to phrase it as a question. It may also help to state what you have tried already.
Is it possible to filter on tags when agenda constructs its view? I have tried the following to show only work related appointments:
("j" "Jobb"
((agenda ""
((org-agenda-skip-function '(org-agenda-skip-entry-if 'notregexp":jobb:"))))
(tags-todo "jobb"))
((org-agenda-compact-blocks nil)))
This works only if the actual appointment is directly tagged, but not if the appointment inherits its tag from a parent headline like this:
* Tider :jobb:
** Millas arbetstider
<2012-04-11 ons 05:00-09:00>
<2012-04-12 tor 04:15-08:30>
<2012-04-13 fre 14:30-18:30>
Is there another way to do this so that appointments that inherits its tag shows up?
The issue is in how org-agenda-skip-entries-if interacts with 'notregexp. It will skip any entries that do not match :jobb:. Even though the later entries inherit the tag, it is not explicitly listed and so they are skipped. There also does not seem to be any built-in method to match (or not match) on tags using org-agenda-skip-entries-if. If there is such a function it would likely be the more efficient method of looking for the tags, but I'm not aware of such a function.
You instead have to create a custom function that will provide the desired search-format.
If you change your agenda command to:
("j" "Jobb"
((agenda ""
((org-agenda-skip-function '(zin/org-agenda-skip-tag "jobb" 't))))
(tags-todo "jobb"))
((org-agenda-compact-blocks nil)))
and define zin/org-agenda-skip-tag as:
(defun zin/org-agenda-skip-tag (tag &optional others)
"Skip all entries that correspond to TAG.
If OTHERS is true, skip all entries that do not correspond to TAG."
(let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
(current-headline (or (and (org-at-heading-p)
(point))
(save-excursion (org-back-to-heading)))))
(if others
(if (not (member tag (org-get-tags-at current-headline)))
next-headline
nil)
(if (member tag (org-get-tags-at current-headline))
next-headline
nil))))
You will get what I understand to be your desired agenda view. If I have it backwards and the entries on the next 3 days should not be present, you simply have to change the function to (zin/org-agenda-skip-tag "jobb") or (zin/org-agenda-skip-tag "jobb" 'nil), they are equivalent in this case.
Agenda View
In this case test-new is the name of the org-file I was using, it can be ignored. I also set both headlines to TODO to have them visible when testing the function, since I was restricting the agenda to only the one file.
Week-agenda (W15):
Monday 9 April 2012 W15
Tuesday 10 April 2012
Wednesday 11 April 2012
test-new: 5:00- 9:00 TODO Millas arbetstider :jobb::
Thursday 12 April 2012
test-new: 4:15- 8:30 TODO Millas arbetstider :jobb::
Friday 13 April 2012
test-new: 14:30-18:30 TODO Millas arbetstider :jobb::
Saturday 14 April 2012
Sunday 15 April 2012
================================================================================
Headlines with TAGS match: jobb
test-new: TODO Tider :jobb:
test-new: TODO Millas arbetstider :jobb::
After using the function in Jonathan's answer for several months to do this kind of per-block filtering, I found myself wanting something capable of dealing with more sophisticated queries (like the match strings used by the other block types), and I figured I'd post it here for anyone who stumbles across this question in the future.
EDIT: The original implementation of my/org-match-at-point-p is now somewhat out of date. The Org mode sources are now lexically scoped, which changes the contract of org-make-tags-matcher. It used to be that the todo and tags-list variables needed to be dynamically scoped around the call to org-make-tags-matcher, whereas now they seem to be passed to the function returned from the call. (Yay! This is so much better!) I've adapted the code below to match the new version, but I don't use Org mode much anymore, so it's only been lightly tested.
(defun my/org-match-at-point-p (match)
"Return non-nil if headline at point matches MATCH.
Here MATCH is a match string of the same format used by
`org-tags-view'."
(funcall (cdr (org-make-tags-matcher match))
(org-get-todo-state)
(org-get-tags-at)
(org-reduced-level (org-current-level))))
(defun my/org-agenda-skip-without-match (match)
"Skip current headline unless it matches MATCH.
Return nil if headline containing point matches MATCH (which
should be a match string of the same format used by
`org-tags-view'). If headline does not match, return the
position of the next headline in current buffer.
Intended for use with `org-agenda-skip-function', where this will
skip exactly those headlines that do not match."
(save-excursion
(unless (org-at-heading-p) (org-back-to-heading))
(let ((next-headline (save-excursion
(or (outline-next-heading) (point-max)))))
(if (my/org-match-at-point-p match) nil next-headline))))
In case you're still using the older version of Org mode, here is the original code. Note that this version assumes that the file in which my/org-match-at-point-p is defined is lexically scoped; if not, you can safely replace the my/defun-dyn macro with a simple defun.
(defmacro my/defun-dyn (&rest def)
"As `defun', but always in dynamic scope.
A function defined in this way ignores the value of
`lexical-binding' and treats it as if it were nil.
\(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)"
(declare (debug defun)
(indent defun)
(doc-string 3))
`(eval '(defun ,#def) nil))
(my/defun-dyn my/org-match-at-point-p (match &optional todo-only)
"Return non-nil if headline at point matches MATCH.
Here MATCH is a match string of the same format used by
`org-tags-view'.
If the optional argument TODO-ONLY is non-nil, do not declare a
match unless headline at point is a todo item."
(let ((todo (org-get-todo-state))
(tags-list (org-get-tags-at)))
(eval (cdr (org-make-tags-matcher match)))))
It is possible to filter the Agenda Dispatcher by hitting "/" in the agenda view.
"/" =
Search for a regular expression in all agenda files and additionally
in the files listed in org-agenda-text-search-extra-files. This uses
the Emacs command multi-occur. A prefix argument can be used to
specify the number of context lines for each match...
I'm doing a bit of programming here and there in Emacs Lisp, but I'm not entirely sure how to go about certain things.
I'm trying to insert a whole month of dates, each on a new line like the list below:
January
01/01/09 Mon:
02/01/09 Tue:
03/01/09 Wed:
etc
How would I go about doing that? I've found how to format dates, but I can't find how to loop over a certain range of dates (in this instance to loop round a whole month and print a date for each day in the month).
Has anyone got some pointers they could give me on how to get started?
The functions you want are 'encode-time, 'format-time-string, and 'decode-time.
For the proper documentation, either C-h f function-name or will give you the documentation for the function, or the general elisp info pages can be found here: C-h i m elisp RET m time conversion RET
Here's that snippet:
(defun my-insert-dates ()
"insert a bunch of dates"
(interactive)
(let* ((month 3)
(day 1)
(time (encode-time 1 1 0 day month 2009)))
(while (= (nth 4 (decode-time time)) month)
(insert (format-time-string "%D %a:\n" time))
(setq day (1+ day))
(setq time (encode-time 1 1 0 day month 2009)))))
I couldn't find how to determine the number of days in a given month (sure, you could hard-code it, but then you've got to deal with leap years). Luckily, 'encode-time does all the addition for you, so if you pass it the equivalent of "February 31", it'll return "March 3" (assuming 28 days).
I would have done something like this, if you don't mind using the calendar feature...
(require 'calendar)
(defun display-a-month (day month year)
(insert (format "%s\n" (calendar-date-string (list month day year))))
(if (< day 30)
(display-a-month (+ day 1) month year)))
You can find help using describe-function (M-x describe-function or C-h f as said before); M-x apropos will give you a list of functions related to something and even better people on irc.freenode.org / #emacs will answer all you questions.
btw, the question was "insert a whole month" not "insert first day of each month" :) depends if you read dd/mm/yyyy of mm/dd/yyyy
Slight variation on Trey's answer using dotimes:
(defun my-insert-dates ()
"insert the first day of each month"
(interactive)
(dotimes (mo 12)
(insert (format-time-string "%D %a:\n" (encode-time 1 1 0 1 (1+ mo) 2009)))))