在Emacs中将光标移动到12个月旋转日历上的日期的算法

law*_*ist 7 emacs elisp

目标:该线程的目标是创建两(2)个数学公式,以便在函数lawlist-calendar-cursor-to-visible-date(下面)中用@lawlist替换长手解决方案.

                                                            故事问题

现在,Emacs中存在一个12个月的日历,一次向前和向后滚动一个月(或更多).该功能lawlist-calendar-cursor-to-visible-date用于为指定事件(例如,生日,假期,约会等)的覆盖标记日期; 或者,只需将光标移动到特定日期.@lawlist已经设计了一个长手的解决方案,它没有完全使用数学方程来计算显示的365天中每一天的光标位置.有可能创建两(2)个简洁算法来替换长手解决方案.

可以在此处找到12个月滚动日历的工作草案(没有长手解决方案):

     /sf/answers/1498640811/

传说:

displayed-month (数字1到12)是显示在缓冲区左上角的月份,随着12个月日历向前或向后滚动,这个月会发生变化.

目标month(数字1到12)是我们需要从两个数学公式与援助,以找到月-根据日期被标记(例如,生日,节日,约会)的位置不同而不同,这取决于displayed-month在缓冲区的左上角.目标month可以在12个可能的位置中的任何一个.有三(3)个可能的x轴坐标(即,6,31,或56).有四(4)个可能的y轴坐标(即,0,9,1827).[引用x/y坐标:http: //www.mathsisfun.com/data/cartesian-coordinates.html ]

A row定义为水平3个月.

A column定义为垂直4个月.

第一forumula必须等于0,9,1827时的点是否在取决于row即,从顶部到底部- 1,2,3或4.

第二forumula必须等于6,31,或56时的点是否在取决于column即,从左至右- 1,2或3.

示例:

  • 如果displayed-month是1月(即1)且目标month是8月(即8),那么row等于18并且column等于31.

  • 如果displayed-month是2月(即2)且目标month是8月(即8),则row等于18column等于6.

  • 如果displayed-month是3月(即3)且目标month是8月(即8),则row等于9column等于56.

  • 如果displayed-month是4月(即4)且目标month是8月(即8),则row等于9column等于31.

  • 如果displayed-month是5月(即5)且目标month是8月(即8),则row等于9column等于6.

12个月的日历如下所示,因为布局一次向前滚动一个月:

;;  1 2 3
;;  4 5 6
;;  7 8 9
;;  10 11 12

;;  2 3 4
;;  5 6 7
;;  8 9 10
;;  11 12 1

;;  3 4 5
;;  6 7 8
;;  9 10 11
;;  12 1 2

;;  4 5 6
;;  7 8 9
;;  10 11 12
;;  1 2 3

;;  5 6 7
;;  8 9 10
;;  11 12 1
;;  2 3 4

;;  6 7 8
;;  9 10 11
;;  12 1 2
;;  3 4 5

;;  7 8 9
;;  10 11 12
;;  1 2 3
;;  4 5 6

;;  8 9 10
;;  11 12 1
;;  2 3 4
;;  5 6 7

;;  9 10 11
;;  12 1 2
;;  3 4 5
;;  6 7 8

;;  10 11 12
;;  1 2 3
;;  4 5 6
;;  7 8 9

;;  11 12 1
;;  2 3 4
;;  5 6 7
;;  8 9 10

;;  12 1 2
;;  3 4 5
;;  6 7 8
;;  9 10 11
Run Code Online (Sandbox Code Playgroud)

@lawlist的长期解决方案如下:

(defun lawlist-calendar-cursor-to-visible-date (date)
  "Move the cursor to DATE that is on the screen."
  (let* (
      (month (calendar-extract-month date))
      (day (calendar-extract-day date))
      (year (calendar-extract-year date))
      (first-of-month-weekday (calendar-day-of-week (list month 1 year))))
    (goto-line
      (+ 3
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        (cond
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ((and
              (eq displayed-month 1)
              (memq month `(1 2 3)))
            0)
          ((and
              (eq displayed-month 1)
              (memq month `(4 5 6)))
            9)
          ((and
              (eq displayed-month 1)
              (memq month `(7 8 9)))
            18)
          ((and
              (eq displayed-month 1)
              (memq month `(10 11 12)))
            27)
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ((and
              (eq displayed-month 2)
              (memq month `(2 3 4)))
            0)
          ((and
              (eq displayed-month 2)
              (memq month `(5 6 7)))
            9)
          ((and
              (eq displayed-month 2)
              (memq month `(8 9 10)))
            18)
          ((and
              (eq displayed-month 2)
              (memq month `(11 12 1)))
            27)
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ((and
              (eq displayed-month 3)
              (memq month `(3 4 5)))
            0)
          ((and
              (eq displayed-month 3)
              (memq month `(6 7 8)))
            9)
          ((and
              (eq displayed-month 3)
              (memq month `(9 10 11)))
            18)
          ((and
              (eq displayed-month 3)
              (memq month `(12 1 2)))
            27)
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ((and
              (eq displayed-month 4)
              (memq month `(4 5 6)))
            0)
          ((and
              (eq displayed-month 4)
              (memq month `(7 8 9)))
            9)
          ((and
              (eq displayed-month 4)
              (memq month `(10 11 12)))
            18)
          ((and
              (eq displayed-month 4)
              (memq month `(1 2 3)))
            27)
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ((and
              (eq displayed-month 5)
              (memq month `(5 6 7)))
            0)
          ((and
              (eq displayed-month 5)
              (memq month `(8 9 10)))
            9)
          ((and
              (eq displayed-month 5)
              (memq month `(11 12 1)))
            18)
          ((and
              (eq displayed-month 5)
              (memq month `(2 3 4)))
            27)
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ((and
              (eq displayed-month 6)
              (memq month `(6 7 8)))
            0)
          ((and
              (eq displayed-month 6)
              (memq month `(9 10 11)))
            9)
          ((and
              (eq displayed-month 6)
              (memq month `(12 1 2)))
            18)
          ((and
              (eq displayed-month 6)
              (memq month `(3 4 5)))
            27)
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ((and
              (eq displayed-month 7)
              (memq month `(7 8 9)))
            0)
          ((and
              (eq displayed-month 7)
              (memq month `(10 11 12)))
            9)
          ((and
              (eq displayed-month 7)
              (memq month `(1 2 3)))
            18)
          ((and
              (eq displayed-month 7)
              (memq month `(4 5 6)))
            27)
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ((and
              (eq displayed-month 8)
              (memq month `(8 9 10)))
            0)
          ((and
              (eq displayed-month 8)
              (memq month `(11 12 1)))
            9)
          ((and
              (eq displayed-month 8)
              (memq month `(2 3 4)))
            18)
          ((and
              (eq displayed-month 8)
              (memq month `(5 6 7)))
            27)
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ((and
              (eq displayed-month 9)
              (memq month `(9 10 11)))
            0)
          ((and
              (eq displayed-month 9)
              (memq month `(12 1 2)))
            9)
          ((and
              (eq displayed-month 9)
              (memq month `(3 4 5)))
            18)
          ((and
              (eq displayed-month 9)
              (memq month `(6 7 8)))
            27)
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ((and
              (eq displayed-month 10)
              (memq month `(10 11 12)))
            0)
          ((and
              (eq displayed-month 10)
              (memq month `(1 2 3)))
            9)
          ((and
              (eq displayed-month 10)
              (memq month `(4 5 6)))
            18)
          ((and
              (eq displayed-month 10)
              (memq month `(7 8 9)))
            27)
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ((and
              (eq displayed-month 11)
              (memq month `(11 12 1)))
            0)
          ((and
              (eq displayed-month 11)
              (memq month `(2 3 4)))
            9)
          ((and
              (eq displayed-month 11)
              (memq month `(5 6 7)))
            18)
          ((and
              (eq displayed-month 11)
              (memq month `(8 9 10)))
            27)
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ((and
              (eq displayed-month 12)
              (memq month `(12 1 2)))
            0)
          ((and
              (eq displayed-month 12)
              (memq month `(3 4 5)))
            9)
          ((and
              (eq displayed-month 12)
              (memq month `(6 7 8)))
            18)
          ((and
              (eq displayed-month 12)
              (memq month `(9 10 11)))
            27) )
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          (/ (+ day  -1
            (mod
              (- (calendar-day-of-week (list month 1 year)) calendar-week-start-day)
                7))
                  7)))
    (move-to-column
      (+ 
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        (cond
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ((and
              (eq displayed-month 1)
              (memq month `(1 4 7 10)))
            6)
          ((and
              (eq displayed-month 1)
              (memq month `(2 5 8 11)))
            31)
          ((and
              (eq displayed-month 1)
              (memq month `(3 6 9 12)))
            56)
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ((and
              (eq displayed-month 2)
              (memq month `(2 5 8 11)))
            6)
          ((and
              (eq displayed-month 2)
              (memq month `(3 6 9 12)))
            31)
          ((and
              (eq displayed-month 2)
              (memq month `(4 7 10 1)))
            56)
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ((and
              (eq displayed-month 3)
              (memq month `(3 6 9 12)))
            6)
          ((and
              (eq displayed-month 3)
              (memq month `(4 7 10 1)))
            31)
          ((and
              (eq displayed-month 3)
              (memq month `(5 8 11 2)))
            56)
          ;;  4 5 6
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ((and
              (eq displayed-month 4)
              (memq month `(4 7 10 1)))
            6)
          ((and
              (eq displayed-month 4)
              (memq month `(5 8 11 2)))
            31)
          ((and
              (eq displayed-month 4)
              (memq month `(6 9 12 3)))
            56)
          ;;  5 6 7
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ((and
              (eq displayed-month 5)
              (memq month `(5 8 11 2)))
            6)
          ((and
              (eq displayed-month 5)
              (memq month `(6 9 12 3)))
            31)
          ((and
              (eq displayed-month 5)
              (memq month `(7 10 1 4)))
            56)
          ;;  6 7 8
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ((and
              (eq displayed-month 6)
              (memq month `(6 9 12 3)))
            6)
          ((and
              (eq displayed-month 6)
              (memq month `(7 10 1 4)))
            31)
          ((and
              (eq displayed-month 6)
              (memq month `(8 11 2 5)))
            56)
          ;;  7 8 9
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ((and
              (eq displayed-month 7)
              (memq month `(7 10 1 4)))
            6)
          ((and
              (eq displayed-month 7)
              (memq month `(8 11 2 5)))
            31)
          ((and
              (eq displayed-month 7)
              (memq month `(9 12 3 6)))
            56)
          ;;  8 9 10
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ((and
              (eq displayed-month 8)
              (memq month `(8 11 2 5)))
            6)
          ((and
              (eq displayed-month 8)
              (memq month `(9 12 3 6)))
            31)
          ((and
              (eq displayed-month 8)
              (memq month `(10 1 4 7)))
            56)
          ;;  9 10 11
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ((and
              (eq displayed-month 9)
              (memq month `(9 12 3 6)))
            6)
          ((and
              (eq displayed-month 9)
              (memq month `(10 1 4 7)))
            31)
          ((and
              (eq displayed-month 9)
              (memq month `(11 2 5 8)))
            56)
          ;;  10 11 12
          ;;  1 2 3
          ;;  4 5 6
          ;;  7 8 9
          ((and
              (eq displayed-month 10)
              (memq month `(10 1 4 7)))
            6)
          ((and
              (eq displayed-month 10)
              (memq month `(11 2 5 8)))
            31)
          ((and
              (eq displayed-month 10)
              (memq month `(12 3 6 9)))
            56)
          ;;  11 12 1
          ;;  2 3 4
          ;;  5 6 7
          ;;  8 9 10
          ((and
              (eq displayed-month 11)
              (memq month `(11 2 5 8)))
            6)
          ((and
              (eq displayed-month 11)
              (memq month `(12 3 6 9)))
            31)
          ((and
              (eq displayed-month 11)
              (memq month `(1 4 7 10)))
            56)
          ;;  12 1 2
          ;;  3 4 5
          ;;  6 7 8
          ;;  9 10 11
          ((and
              (eq displayed-month 12)
              (memq month `(12 3 6 9)))
            6)
          ((and
              (eq displayed-month 12)
              (memq month `(1 4 7 10)))
            31)
          ((and
              (eq displayed-month 12)
              (memq month `(2 5 8 11)))
            56) )
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          (* 3 (mod
            (- (calendar-day-of-week date) calendar-week-start-day)
              7))))))
Run Code Online (Sandbox Code Playgroud)

ASh*_*lly 4

我一定错过了一些东西,因为看起来公式就像(伪代码)一样简单:

first  = 9 * ( rows - 1 ) 
second = 6 + 25 * ( cols - 1 )
Run Code Online (Sandbox Code Playgroud)

根据您的编辑,您可以计算要移动的行和列:

if target > display
   difference = target - display
else 
   difference = 12 + target - display
 rows = difference / 3 
 cols = difference % 3
 rowmove = 9 * rows 
 colmove = 6 + 25 * cols
Run Code Online (Sandbox Code Playgroud)

然后使用上面的公式。

我对 elisp 的尝试:

(let difference (if (>= target-month display-month) 
                      (- target-month display-month) 
                    (- (+ target-month 12) display-month)))
(let rows (/ difference 3))
(let cols (% difference 3))
(let rowmove (* 9 rows))   
(let colmove (+ 6 (* 25 cols)))
Run Code Online (Sandbox Code Playgroud)