Создание орг-таблиц по результатам блока кода

Я пытаюсь создать оргтаблицу на основе содержимого CSV-файла, в котором используется ";" как разделитель.

Я думал, что было бы легко иметь блок исходного кода для "cat" содержимого файла, а затем передать результат функции, которая создает таблицу, но я застрял: я не могу найти способ использовать " результаты" первого блока исходного кода. Функция, которую я знаю (org-table-convert-region), ожидает, что регион будет работать, и я не знаю, как передать текст "cat" в качестве региона.

#+NAME: csvraw
#+BEGIN_SRC sh :results raw
  cat afile.csv
#+END_SRC

Я был бы признателен за вашу помощь в создании блока кода, который создает орг-таблицу из моего CSV-файла, который содержит строки, подобные следующим:

ID;Region;SubRegion;Area;No
1234;Asia;India;45;2
24251;Europe;Romania;456;67
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
940
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
(defun jea-convert-csv-to-org-table (fname)
  (interactive "fCSV to convert: ")
  (let ((result '("|-\n")))
    (with-temp-buffer
      (save-excursion (insert-file-contents-literally fname))
      (while (and (not (eobp)) (re-search-forward "^\\(.+\\)$" nil t nil))
        (push (concat "|" (replace-regexp-in-string ";" "|" (match-string 1)) "|\n")
              result))
      (push '"|-\n" result))
    (concat (seq-mapcat #'identity (reverse result)))))

установите код elisp в файл ~/.emacs и перезапустите emacs. Или, еще лучше, eval его существование (CTRL+x, CTRL+e или ALT+x eval-last-sexp).

#+NAME: csvraw
#+BEGIN_SRC elisp :results raw
  (jea-convert-csv-to-org-table "/Users/jamesanderson/Downloads/test1.csv")
#+END_SRC

обратите внимание на изменение elisp с sh выше. вот гифка в действии: emacs конвертирует csv в таблицу org

Код не оптимизирован для больших файлов и, честно говоря, довольно быстро собирается. Но, после небольшого тестирования, похоже, работает.

Вы могли бы повысить эффективность, просто изменив текст буфера и извлекая его весь сразу, (defun nvp-convert-csv-to-org-table (fname) (interactive (list (read-file-name "CSV to convert: "))) (with-temp-buffer (save-excursion (insert-file-contents-literally fname)) (while (not (eobp)) (insert "|") (while (search-forward ";" (line-end-position) 'move) (replace-match "|")) (insert "|") (forward-line)) (buffer-string)))

Rorschach 10.04.2019 08:26

Джеймс, большое спасибо за ваш ответ и за то, что нашли время, чтобы ответить на мой запрос. Я следовал вашим инструкциям, используя пример файла csv, упомянутый в моем вопросе, но что-то идет не так: функция создает новый буфер и копирует содержимое csv файл есть, но зависает, вынуждая меня <kbd>Ctrl-g</kbd> несколько раз восстановить контроль над emacs.

picchiolu 10.04.2019 10:28

@jenesaisquoi, спасибо, что предложили улучшения. Попробую вашу версию и отпишусь здесь, когда закончу.

picchiolu 10.04.2019 10:30

@jenesaisquoi правильно: я использовал Edebug, чтобы выяснить, что происходит, и действительно, цикл while продолжается вечно: он продолжает объединять строку |\n с result.

picchiolu 10.04.2019 10:57

Джеймс, я изменил предложенный вами код, добавив условие завершения цикла while. Я отредактировал ваш ответ, чтобы отразить изменение: я думаю, мне придется подождать, пока поправка будет рассмотрена экспертами, чтобы она стала видимой.

picchiolu 10.04.2019 12:27

@jenesaisquoi Ваша версия работает очень хорошо, спасибо! Я убрал условие not(eobp) из вашего кода и использовал его в Джеймсе.

picchiolu 10.04.2019 12:37

это большие улучшения. Я постоянно забываю о with-temp-buffer. и я должен был протестировать его с более чем одним простым файлом. Я использую org-mode, но у меня никогда не было времени копаться в его коде. Я подозреваю, что в нем есть функции, которые могли бы работать еще лучше. Тем не менее, писать на lisp весело.

James Anderson 10.04.2019 15:44

Написание лиспа является весело, но рабочим предположением всегда должно быть: «в организационном режиме уже должно быть что-то встроенное для этого» для любого значения «this». Смотрите мой ответ для доказательства в этом конкретном случае :-)

NickD 10.04.2019 18:28

Существует org-table-convert-region (связанный с C-c |), который может довольно просто выполнить преобразование. Единственный трюк — указать ; в качестве разделителя. Вы можете сделать это, вызвав его с правильным аргументом префикса - строка документа говорит:

(org-table-convert-region BEG0 END0 &optional SEPARATOR)

Convert region to a table.

The region goes from BEG0 to END0, but these borders will be moved
slightly, to make sure a beginning of line in the first line is included.

SEPARATOR specifies the field separator in the lines.  It can have the
following values:

(4)     Use the comma as a field separator
(16)    Use a TAB as field separator
(64)    Prompt for a regular expression as field separator
integer  When a number, use that many spaces, or a TAB, as field separator
regexp   When a regular expression, use it to match the separator
nil      When nil, the command tries to be smart and figure out the
         separator in the following way:
         - when each line contains a TAB, assume TAB-separated material
         - when each line contains a comma, assume CSV material
         - else, assume one or more SPACE characters as separator.

Значение (64) — всего три C-u подряд, поэтому процесс выглядит следующим образом:

  • вставьте файл CSV с C-x i.
  • C-x C-x, чтобы пометить вставленное содержимое как активную область.
  • C-u C-u C-u C-c | ; RET

Что еще круче, если оставить пустую строку в CSV-файле между первой строкой и остальными строками, первая строка автоматически станет заголовком в таблице.

И вы также можете обернуть его в блок кода:

#+begin_src elisp :var file = "/tmp/foo.csv" :results raw
  (defun csv-to-table (file)
    (with-temp-buffer
      (erase-buffer)
      (insert-file file)
      (org-table-convert-region (point-min) (point-max) ";")
      (buffer-string)))

  (csv-to-table file)
#+end_src

#+RESULTS:
| a | b | c |
|---+---+---|
| d | e | f |
| g | h | i |

Большое спасибо, что откликнулись на ваш очень информативный ответ. Решение, которое вы предлагаете, компактно и при этом чрезвычайно «разборчиво».

picchiolu 11.04.2019 10:45

Другие вопросы по теме