我正在尝试在.emacs
中实施节气,所以我的“假期”将显示太阳经度超过15度的每个倍数的时间。这是相关的snipplet。
(defun next-solar-term-date (d)
(solar-date-next-longitude d 15))
(defconst solar-term-names
["moderate cold" "severe cold" "spring commerces"
"rain water" "insects awaken" "vernal equinox"
"Ching Ming" "corn rain" "summer commerces"
"corn forms" "corn on ear" "summer solstice"
"minor heat" "great heat" "autumn commerces"
"end of heat" "white dew" "autumnal equinox"
"cold dew" "frost" "winter commerces"
"light snow" "heavy snow" "winter solstice"])
(setq solar-terms-holidays
(let* ((k 0) (mylist nil))
(dotimes (k 4);k=season
(let* ((j 0))
(dotimes (j 5);no equinoxes/solstices --- use solar for them
(let* ((i (+ j (* 6 k)))
(month (+ 1 (/ i 2)))
(astronextdate (next-solar-term-date
(calendar-astro-from-absolute
(+ (* 15 i)
(calendar-absolute-from-gregorian
(list 1 1 displayed-year))))))
(s (aref solar-term-names i))
(absnextdate (calendar-absolute-from-astro
astronextdate))
(gregnextdate (calendar-gregorian-from-absolute
(floor absnextdate)))
(compt (* 24 (- absnextdate (floor absnextdate))))
(str (concat s " "
(solar-time-string
compt (if (dst-in-effect absnextdate)
calendar-daylight-time-zone-name
calendar-standard-time-zone-name))))
(d (extract-calendar-day gregnextdate)))
(setq mylist (append mylist
(list
(list 'holiday-fixed month d str))))))))
mylist))
但是,emacs(Gentoo上的版本23.2-r2)抱怨显示年份在启动时是一个无效变量,并且尝试使用 Mx日历RET 生成日历没有帮助无论是。知道如何解决这个问题吗? (当然不是在我的.emacs
中定义显示年份,因为这肯定搞砸了其他一切......)
答案 0 :(得分:3)
因为您没有将符号displayed-year
绑定到值。查看let*
的{{1}}绑定中的最后一行:
astronextdate
该符号未绑定到任何值,因此您得到一个void变量错误。该变量在 (list 1 1 displayed-year))))))
库中定义,该库具有文档:
calendar
所以,看起来你只需要添加:
;; A note on free variables:
;; The calendar passes around a few dynamically bound variables, which
;; unfortunately have rather common names. They are meant to be
;; available for external functions, so the names can't be changed.
;; displayed-month, displayed-year: bound in calendar-generate, the
;; central month of the 3 month calendar window
强制Emacs加载预先定义变量的包。
那说,它将被定义,但尚未受约束。您应该将代码更改为不假定静态绑定(require 'calendar)
,但应将其转换为按需计算这些代码的函数,因为solar-terms-holidays
仅在日历实际运行时绑定...
所以,一个可能的解决方案是执行以下操作,按如下方式包装displayed-year
以确保变量绑定,就像您期望的那样:
setq
答案 1 :(得分:1)
计算需要推迟到displayed-year
可用,这可以通过用以下两个替换粘贴中的最后一个表达式来实现:
(defun solar-term (i month)
(let* ((astronextdate (next-solar-term-date
(calendar-astro-from-absolute
(+ (* 15 i)
(calendar-absolute-from-gregorian
(list 1 1 displayed-year))))))
(s (aref solar-term-names i))
(absnextdate (calendar-absolute-from-astro
astronextdate))
(gregnextdate (calendar-gregorian-from-absolute
(floor absnextdate)))
(compt (* 24 (- absnextdate (floor absnextdate))))
(str (concat s " "
(solar-time-string
compt (if (dst-in-effect absnextdate)
calendar-daylight-time-zone-name
calendar-standard-time-zone-name))))
(d (extract-calendar-day gregnextdate)))
(holiday-fixed month d str)))
(setq solar-terms-holidays
(let* ((mylist nil))
(dotimes (k 4) ;k=season
(dotimes (j 5) ;no equinoxes/solstices --- use solar for them
(let* ((i (+ j (* 6 k)))
(month (+ 1 (/ i 2))))
(push `(solar-term ,i ,month) mylist))))
mylist))