प्रारूप-टाइम-स्ट्रिंग जैसे फ़ंक्शन को लागू करने का सबसे आसान तरीका क्या है


12

format-time-string समारोह एक स्ट्रिंग लेता है, और कि स्ट्रिंग (पात्रों द्वारा preceeded में विशेष निर्माणों का एक सेट की जगह %) कुछ विशिष्ट पाठ के साथ।

मैं अपने खुद के एक समारोह में इस तरह की कार्यक्षमता लागू करना चाहता हूं:

  • मैं वर्ण और जैसे प्रतीकों के बीच एक alist है: '((?n . name) (?r . reputation))
  • फ़ंक्शन को एक स्ट्रिंग की तरह लेना चाहिए "My name is %n, and my rep is %r"
  • यह बदलना चाहिए %nऔर %rचर के मूल्य के साथ nameऔर reputationहै, और परिणाम लौटने।
  • इसे %%ऐसे ही हैंडल करना चाहिए format-time-string(इसे इसके साथ बदलें %)।

इस फ़ंक्शन को लागू करने का सबसे आसान तरीका क्या है?
क्या कोई पुस्तकालय या कार्य है जो इसे सुगम बनाएगा? %%सही ढंग से संभालना महत्वपूर्ण है।

जवाबों:


19

उपयोग किए जाने वाले डिफ़ॉल्ट कार्य हैं format-specऔर format-spec-make:

(let* ((name "Malabarba")
       (reputation "good")
       (fs (format-spec-make ?n name ?r reputation)))
  (format-spec "My name is %n, with a %r reputation.  %% is kept." fs))

1
अच्छा है, इस तरह की चीज़ों के Emacs में पहले से मौजूद होने की उम्मीद नहीं थी। क्या विशेष रूप से अच्छा है कि इसमें शामिल अमान्य प्रारूप कोड के लिए अल्पविकसित त्रुटि हैंडलिंग है।
वामासा

7

चूँकि स्ट्रिंग्स से निपटने के लिए elisp के बजाय आदिम सुविधाएं हैं, इसलिए अपने प्रारूप स्ट्रिंग को बफर में डालना और उस पर पुनरावृति करना बेहतर है:

(defvar malabarba-alist '((?n . "Malabarba") (?r . 7488) (?% . "%")))

(defun malabarba-format (string)
  (with-temp-buffer
    (insert string)
    (goto-char 1)
    (while (search-forward "%" nil t)
      (let ((s (cdr (assoc (char-after) malabarba-alist))))
        (cond
          (s (delete-char -1) (delete-char 1) (insert (format "%s" (eval s))))
          (t (unless (eobp) (forward-char))))))
    (buffer-string)))

एक मामूली सूक्ष्मता - यह तब नहीं टूटता जब %स्ट्रिंग के अंत में एक अकेला होता है क्योंकि बफर के अंत में char-afterलौटता है nil


हाँ, यह दृष्टिकोण, स्ट्रिंग के माध्यम से एक बार, @AlanShutko द्वारा उपयोग किया जाता है, और अधिक समझ में आता है। मैंने अपना उत्तर हटा दिया है।
ड्रू

3

यहाँ कोड है कि मैं एक नकली कैलेंडर के लिए प्रारूप-समय-स्ट्रिंग के लिए उपयोग करता हूं:

(defun mystcal-format-time (format-string time)
  "Format time
%Y is the year.
%m is the numeric month.
%B is the full name of the month.
%d is the day of the month, zero-padded, %e is blank-padded.
%u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.
%A is the locale's full name of the day of week.
%H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H
 only blank-padded, %l is like %I blank-padded.
%p is the locale's equivalent of either AM or PM.
%M is the minute.
%S is the second."
  (let* (output
         (start 0)
         (decoded-time (if (listp time)
                           time
                         (mystcal-decode-time time)))
         (turn (nth 0 decoded-time))
         (minute (nth 1 decoded-time))
         (hour (nth 2 decoded-time))
         (day (nth 3 decoded-time))
         (month (mystcal-month decoded-time))
         (year (nth 5 decoded-time))
         (weekday (mystcal-weekday-of-day day))
         (hour12 (mod hour 12)))
    (save-match-data
      (while (string-match "%" format-string start)
        (let ((index (match-beginning 0)))
          ;; First copy non-format text
          (setq output (concat output (substring format-string start 
                                                 index)))
          ;; Process format codes here
          (let (fmted)
            (setq output (concat output 
                                 (case (aref format-string (1+ index))
                                   (?Y (number-to-string year))
                                   (?m (number-to-string month))
                                   (?B (mystcal-month-name month))
                                   (?d (format "%02d" day))
                                   (?e (format "%2d" day))
                                   (?u (number-to-string (if (zerop weekday)
                                                             7
                                                           weekday)))
                                   (?w (number-to-string weekday))
                                   (?A (mystcal-weekday-name 
                                        (mystcal-weekday-of-day day)))
                                   (?H (format "%02d" hour))
                                   (?k (format "%2d" hour))
                                   (?I (format "%02d" (if (zerop hour12) 12 hour12)))
                                   (?l (format "%2d" (if (zerop hour12) 12 hour12)))
                                   (?p (if (< hour 12)
                                           "AM" "PM"))
                                   (?M (format "%02d" minute))
                                   (?S "00")))))
          (setq start (+ 2 index)))))
    (setq output (concat output (substring format-string start)))
    output))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.