(buffer-substring-no-properties) backslash handling - elisp
Good afternoon. In the text, the record
#samp{\}
, the code
(buffer-substring-no-properties (+ nach 4) (- (point) 4))
is captured here this region, at the output of the
"#samp{\\}"
function. The question is how to get the non-escaped forward slash. Thank you
"#samp{\\}" represents the string #samp{\}. It's not different to the original text.
When you ask Emacs to print the return value of buffer-substring-no-properties you are seeing the printed representation of a string -- which is equivalent to the double-quoted read syntax for strings (as you would write it in code) -- in which a single backslash must be escaped with another.
Refer to the elisp manual:
C-hig (elisp)Printed Representation
C-hig (elisp)Syntax for Strings
C-hig (elisp)Nonprinting Characters
Changes further along the code gave the result, namely, not a correction of the record of the read line, but a change in the insertion of the ill-fated line "#samp {\\}" back into the text. The function is presented
(defun zamenaOBJ (спсОбктв)
"Зменить obzx оригиналом"
(goto-char 1)
(while (re-search-forward "[Bb]jkt\\([[:digit:]]\\)+" nil t 1)
(replace-match (cdr (assoc (downcase (match-string 0)) спсОбктв)) t)))
Here is the data at the time of the error (what was received
(buffer-substring-no-properties)
and saved in the associative list
(cdr (assoc (downcase (match-string 0)) спсОбктв))
"#samp{\\}"
The error itself
(replace-match (cdr (assoc (downcase (match-string 0)) спсОбктв)) t)
Invalid use of ‘\’ in replacement text
If it was written like this:
(replace-match (prin1-to-string (cdr (assoc (downcase (match-string 0)) спсОбктв)) t))
все замены по тексту были окружены двойной кавычкой, если же указывался аргумент noescape в t для prin1-to-string:
(replace-match (prin1-to-string (cdr (assoc (downcase (match-string 0)) спсОбктв)) t) t)
or
(replace-match (princ (cdr (assoc (downcase (match-string 0)) спсОбктв)) t))
the error came back again
Solved by adding the second argument literal replace-match
(replace-match (cdr (assoc (downcase (match-string 0)) спсОбктв)) t t)
Related
Why do I get "application: not a procedure" with this for loop in Racket?
The following code reads a csv file and based on its content generates a Prolog program: #!/usr/bin/env racket #lang racket/base (define (overwrite-s-to-f fname s); Will create fname and write overwriting the previous content. (with-output-to-file #:exists 'truncate fname (lambda () (displayln s)))) (define (c-o-a-line-to-f fname s); Will append a string to fname or create it if does not exist. Appends a new line. (with-output-to-file #:exists 'append fname (lambda () (displayln s)))); (define fname "women.csv") (define pl-fname "females-by-Racket.pl") (require racket/file) (define content (file->lines fname)) (define disc-line (string-append ":-discontiguous(" (string-replace (car content) "Name," "") ").\n")) (overwrite-s-to-f pl-fname disc-line) (define list-of-verbs (string-split (string-replace (car content) "Name," "") ",")) (require racket/string racket/system) (for ((row content));content is a list of strings (let ((list-of-cs (string-split row ","))) (when (equal? (car (cdr list-of-cs)) "+") (displayln row)(let ((cmd (string-append "awesome("(car list-of-cs)").")))(c-o-a-line-to-f pl-fname cmd)(displayln cmd))) (when (equal? (car (cdr (cdr list-of-cs))) "+")(displayln row)(let ((cmd (string-append "and_intelligent("(car list-of-cs)")."))) (c-o-a-line-to-f pl-fname cmd)(displayln cmd))))); TODO: when for each columns 2-last of women.csv The content of women.csv: Name,awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts adriana_chechik,+,,,+,?,+,+,,-,,,,, alysa_gap,+,,,,?,+,+,,-,,,,, anna_de_ville,+,,,,,+,+,,+,-,+,-,-, aurora_jolie,+,+,,,,,,,+,+,+,,+, autumn_falls,,,,,,,,,+,+,-,+,+, casey_calvert,+,,,,,,,,+,+,+,,, dahlia_sky,+,,,,,,+,,,,,,, dominica_lito,+,,,,,,+,,,,,,, ella_knox,,,,,,,,,+,+,+,,+, isabella_clark,+,,,,,,+,,,,,,, jade_kush,,,,,,,,,+,+,,,+, juelz_ventura,+,,,,,+,,,-,-,,,-,+ kapri_styles,,,,,,,,,+,,+,,, kristina_milan,,,,,,,,,+,+,,,+, kylie_sinner,+,+,,,,,,,+,,,,-, leigh_raven,+,,,,,+,,,+,+,,,, maserati,,,,,,,,,+,+,,,+, miosotis,,,,,,,,,+,+,,,+, scarlett_bloom,,,,,,,,,+,+,+,,-, sheena_shaw,,,,,,,,,-,,+,,-, sofia_rose,,,,,,,,,+,,,,+, teanna_trump,+,,,,,,,,+,,+,,, veronica_avluv,+,,,,,,+,,,,,,, yudi_pineda,+,,,,,,,,+,+,,,, females-by-Racket.pl is to look like so: :-discontiguous(awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts). awesome(adriana_chechik). awesome(alysa_gap). awesome(anna_de_ville). awesome(aurora_jolie). and_intelligent(aurora_jolie). awesome(casey_calvert). awesome(dahlia_sky). awesome(dominica_lito). awesome(isabella_clark). awesome(juelz_ventura). awesome(kylie_sinner). and_intelligent(kylie_sinner). awesome(leigh_raven). awesome(teanna_trump). awesome(veronica_avluv). awesome(yudi_pineda). but with more predicates (up to n-1 for each woman where n is the number of columns in women.csv) The names of the columns or the numbers thereof in women.csv are likely to be frequently changed. That is partly why I wish to avoid manually coding for every when. The other concerns are the sheer amount of the lines to code (15 whens for each column) and the risk of error/typo. Is it doable to loop through every cell in list-of-cs in such way that it is taken from list-of-verbs? I've tried this but to no avail (the comment show the error message that I got): (for ((row content)) (let ((list-of-cs (cdr (string-split row ",")))) (for ((cell list-of-cs)) ; application: not a procedure; expected a procedure ; that can be applied to arguments (set! list-of-verbs (cdr (list-of-verbs))) (let ((verb (car list-of-verbs))) (when (equal? cell "+") (displayln row) (let ((cmd (string-append verb "(" (car row) ")."))) (c-o-a-line-to-f pl-fname cmd))) ))))
named let is a useful form to be familiar with: #lang scheme (define (csv->attributes rows) ;; ListOfString -> ListOfString ;; produce "column-header(row-name)" for "+" entries in csv (see example) (let ([fields (string-split (car rows) ",")]) (let next-row ([rows (cdr rows)] [result (list)]) (cond [(null? rows) (reverse result) ] [else (let* ([cells (string-split (car rows) ",")] [name (car cells)]) (let next-cell ([cells (cdr cells)] [fields (cdr fields)] [result result]) (cond [(null? cells) (next-row (cdr rows) result) ] [else (next-cell (cdr cells) (cdr fields) (if (string=? (car cells) "+") (cons (string-append (car fields) "(" name ")") result) result)) ]))) ])))) (define trio '("Name,fast,slow,sidles" "Achilles,+,," "Tortoise,,+," "Crab,,+,+")) Welcome to DrRacket, version 8.5 [cs]. Language: scheme, with debugging. > (csv->attributes trio) ("fast(Achilles)" "slow(Tortoise)" "slow(Crab)" "sidles(Crab)") >
Call of non-procedure in function definition?
I found a short introduction to Scheme online, and I'm having a bit of trouble with this function: (define (title-style str) (let loop ((lc #\space) (i 0) (c (string-ref str 0))) ((if (char=? lc #\space) (string-set! str i (char-upcase c))) (if (= (- (string-length str) 1) i) str (loop c (+ i 1) (string-ref str (+ i 1))))))) (display "star wars iv: a new hope") (display (title-style "star wars iv: a new hope")) When I try calling it, I get this: Error: call of non-procedure: #<unspecified> Call history: title-style.scm:6: loop ... title-style.scm:1: g6 <-- That error comes from Chicken Scheme, I am also getting the same results in Chez Scheme. It converts a string to title case, and from the error messages I got earlier, it does: call of non-procedure: "Star Wars Iv: A New Hope"
I understand what you intend to do, but that's not the right way to structure a conditional expression in Scheme. Also, right before the first if there's a misplaced opening parentheses (which is the one causing the reported error), and you have to advance the recursion in all cases. This should work for non-empty strings: (define (title-style str) (let loop ((lc #\space) (i 0) (c (string-ref str 0))) (cond ((= (- (string-length str) 1) i) str) ((char=? lc #\space) (string-set! str i (char-upcase c)) (loop c (+ i 1) (string-ref str (+ i 1)))) (else (loop c (+ i 1) (string-ref str (+ i 1))))))) But still, it's not the recommended way to write a solution in Scheme, you're mutating the input string along the way, which is discouraged, and you're thinking in terms of indexes. Besides, you're imposing an extra restriction on your input: that the strings must be mutable, and not all Scheme dialects support this by default. A functional tail-recursive style is preferred, where we create a new string as output, leaving the original input untouched and leveraging the rich library of list procedures available in the language; this is what I mean: (define (title-style str) (let loop ((lc #\space) (lst (string->list str)) (acc '())) (cond ((null? lst) (list->string (reverse acc))) ((char=? lc #\space) (loop (car lst) (cdr lst) (cons (char-upcase (car lst)) acc))) (else (loop (car lst) (cdr lst) (cons (car lst) acc)))))) Either way, it works as expected: (title-style "star wars iv: a new hope") => "Star Wars Iv: A New Hope"
How to get Emacs to sort lines by length?
I'd like to be able to highlight a region in Emacs and then sort the region by line length. The closest I've found is the following code which I think will sort by length: (sort-subr t #'forward-line #'end-of-line nil nil (lambda (l1 l2) (apply #'< (mapcar (lambda (range) (- (cdr range) (car range))) (list l1 l2))))) But I don't know how to turn this into an interactive function that lets me use it by highlighting a region. Can someone help?
You can combine the sort-lines command definition with your snippet to form a new command: (defun sort-lines-by-length (reverse beg end) "Sort lines by length." (interactive "P\nr") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (let ;; To make `end-of-line' and etc. to ignore fields. ((inhibit-field-text-motion t)) (sort-subr reverse 'forward-line 'end-of-line nil nil (lambda (l1 l2) (apply #'< (mapcar (lambda (range) (- (cdr range) (car range))) (list l1 l2)))))))))
Call to defmacro with a quoted symbol
I have this data structure (basically): (setq ssm-list '(tasklist ((id . "10525295") (name . "Inbox") (sort_order . "0")))) This works for getting the name: (defun ssm-list-get-prop (list prop) (cdr (assoc prop (car (cdr list))))) (ssm-list-get-prop slack-one-list 'name) What'd I like is to create a macro that will create a defun with the name ssm-list-name (or ssm-list-id) as there are actually a lot more properties in the list. So I tried this: (defmacro ssm-list-prop-defun (field) `(defun ,(intern (concat "ssm-list-" field)) (one-list) (cdr (assoc ,field (car (cdr one-list)))))) (ssm-list-prop-defun 'name) (ssm-list-prop-defun 'id) But the last two calls failed miserably with (wrong-type-argument characterp quote) I tried putting symbol-name in the macro but that didn't help. Is there a way to accomplish this?
You're very close, minor edits gets you a working solution. The problem is that you're mixing symbols and strings. This will work: (defmacro ssm-list-prop-defun (field) ;; note that concat operates on strings `(defun ,(intern (concat "ssm-list-" field)) (one-list) ;; note that you need a symbol here, so quote the ;; result of the call to intern ;; and, if you're always using symbols, ;; might as well use assq (cdr (assq ',(intern field) (car (cdr one-list)))))) ;; pass in a string (ssm-list-prop-defun "name") And here's the variant that uses a symbol: ;; variant that works off a symbol (defmacro ssm-list-prop-defun (field) `(defun ,(intern (concat "ssm-list-" (symbol-name field))) (one-list) (cdr (assq ',field (car (cdr one-list)))))) (ssm-list-prop-defun name)
I think you want to read about defstruct in the cl package: (info "(cl) Structures") (or http://www.gnu.org/software/emacs/manual/html_node/cl/Structures.html#Structures)
Detecting EOF in a Binary File using Scheme
(define (read-all-input) (local ((define line (bytes->list (read-bytes 4)))) (if (eof-object? line) empty (cons line (read-all-input))))) (void (read-all-input)) The above code fails because bytes->list expects an argument of type byte string, but is given #
#lang scheme (define (read-all-input) (let ((b (read-bytes 4))) (cond ((eof-object? b) empty) (else (cons b (read-all-input))) ))) (void (read-all-input)) This function reads bytes into a list of bytes.
I'm not really sure what you want to obtain but this here's my try: (define read-all-input (lambda () (let ((line (read-bytes 4))) (if (eof-object? line) '() (cons (bytes->list line) (read-all-input))))))