Автор Тема: конвертирование текста markdown to odt в pandoc  (Прочитано 6556 раз)

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Всем добрый день!
При конвертировании текста командой pandoc input.md -o output.odt все абзацы получаются выровненными не по-русски, по ширине, а по левому краю. Приходится стиль абзаца вручную менять, что не аккуратненько.
Не знает ли кто способа сразу делать все корректно? Я пробовал указывать свой шаблон при преобразовании, но pandoc вылетае с ошибкой...

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Отвечаю сам себе. Но, может кому-то еще понадобится.

Создаю файл odt в котором оформляю стили, которые использует pandoc, как мне надо - включаю перенос строк в стиле "Основной текст", разное начертание и выравнивание для заголовков различного уровня, формат сносок, таблицы (в т.ч., стиль заголовков таблицы). Этот файл будет шаблоном. Во вложении к сообщению я его приложил.

Затем в тунаре сделал особое действие для конвертации файлов маркдаун в odt:

pandoc --toc -o %f.odt %f --reference-doc=/home/path/my-template.odt
Условия появления - галку на "текстовые файлы" и шаблон имени "*.md"

Если не нужно оглавление, то нужно убрать --toc

Все получается прекрасно, все документы оформляются единообразно. Единственный недостаток - оглавление не генерируется, но на первой странице получаемого файла вставляется соответствующее пустое поле, которое в один клик обновляется по щелчку ПКМ на меню "Обновить указатель"

Пока разбирался, нашел еще возможность перекрестных ссылок внутри текста, которая в маркдауне отсутствует но возникает при использовании pandoc.

Последний автоматически вставляет перед заголовками якоря, ссылаться на которые можно в любом месте текста. При этом текст якоря - это текст соответствующего заголовка в нижнем регистре, вместо пробелов - тире. Ссылаться можно так:
# Заголовок первого уровня
...
А это [перекрестная ссылка](#заголовок-первого-уровня) на этот заголовок

К сожалению, не получается выравнивать текст по правому краю при конвертировании в odt (при конвертации в html проблем нет с использованием тега align)

ps обходное решение может быть в том, чтобы пожертвовать стилем заголовка какого-нибудь ненужного уровня и сделать его выровненным по правому краю. Но это плохой костыль, поскольку соответствующие части текста будут в оглавлении отражаться...
« Последнее редактирование: 12.11.2020 21:50:41 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Не знаю, разрешается ли это правилами форума, поправьте если что. Коль скоро тема посвящена конвертации маркдауна, буду делиться своими рецептами.

В маркдауне стандартный синтаксис вставки картинок такой:
![Рисунок 1 Сведения об объеме заимствований](p1.png)
При этом текст размещается внизу стилем FigureCaption. Этот стиль можно по-своему определить в стилевом файле.

Но иногда требуют изображения подписывать так:
Справа курсивом пишется Рисунок 1
Ниже название рисунка
затем сам рисунок.

В маркдауне нет выравнивания по правой стороне, но есть вставка цитат, причем цитаты могут быть вложенными, т.е. будут отбиваться отступами.

Цитата начинается с символа >. Вложенные цитаты - с нескольких таких символов. Каждый значок > увеличивает абзацный отступ на 1,27 см. Поэтому, чтобы сделать справа надпись Рисунок 1 пишем так:
>>>>>>>>>>>Рисунок 1Чтобы не ошибаться в количестве галочек можно сделать сниппет.
Так же можно сдвигать картинку:

>>>>>>>>>>>Рисунок 1

Сведения об объеме заимствований

>>>>>>>![](p1.png)

МОжет кому-то покажется все это дело корявым, но простой текст, как мне кажется, дает огромную гибкость, в нем можно легко делать сложный поиск и замену регулярными выражениями, как угодно его кромсать, индексировать, в общем масса преимуществ. К тому же файлы получаются меньшими по объему.

В моих планах сделать скриптик, который будет автоматически нумеровать сноски. Это актуально при объединении нескольких текстов на маркдауне, каждый из которых содержит сноски со своей нумерацией, поэтому возможны повторы в номерах сносок. По моей задумке, скриптик будет эту ситуацию исправлять.
« Последнее редактирование: 14.11.2020 22:24:55 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Написал скриптик на питоне footnotes.py, который в автоматическом режиме перенумеровывает сноски (порядок может нарушаться при слиянии файлов, при человеческой ошибке, когда сноска нумеруется номером, который уже занят. (исправлено 5 января 2020 г.)
Спойлер
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import sys

newstr=''
notenum=1
strpos = 0
pozition=0
f = open(sys.argv[1], 'r')
fstr = f.read()
f.close()
''' Делаем различное оформление для знаков сносок
и самих сносок'''

fstr=re.sub ('\n\[\^\d+\]:', r'\n[*]:', fstr)
fstr=re.sub ('\[\^\d+\]', r'[]', fstr)
'''Делаем сплошную нумерацию знаков сносок'''
while pozition != -1:
    pozition = fstr.find('[]',strpos)
    if pozition != -1:
        newstr = newstr+fstr[strpos:pozition]+'[^'+str(notenum)+']'
        strpos = pozition+2
        notenum+=1

newstr = newstr+fstr[strpos:]

'''Делаем сплошную нумерацию сносок'''
fstr = newstr
newstr=''
notenum=1
strpos = 0
pozition=0

while pozition != -1:
    pozition=fstr.find('[*]',strpos)
    if pozition != -1:
        newstr = newstr+fstr[strpos:pozition]+'[^'+str(notenum)+']'
        notenum+=1
        strpos = pozition+3

newstr = newstr+fstr[strpos:]

f = open(sys.argv[1], 'w')

f.write(newstr)
f.close()


Создал особое действие в thunar'e "Упорядочить сноски в md файле"
Команда python3 /home/user/path/footnotes.py %fУсловия появления -- шаблон имени файлв *.md, галки на текстовые и другие файлы

Особенности скрипта:
1. файл переписывается, поэтому нужно на всякий заранее делать резервную копию.

2. Порядок размещения сносок в тексте должен быть таким же как порядок размещения сносок. Сноски отбиваются пустой строкой, без начальных пробелов:


Пример текста [^1] с нарушенной нумерацией сносок[^3]

[^1]: сноска 1

[^3]: эта сноска перенумеруется и будет № 2


PS если кто-то сделает замечания по скрипту, буду очень благодарен, так как чукча не писатель))

PPS Аппетит приходит во время еды. Хочу теперь сделать скрипт, чтобы удобнее было работать с таблицами... Если у кого-то есть какие-нибудь идеи, был бы рад услышать.
« Последнее редактирование: 06.01.2021 20:24:20 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Еще один скрипт для автоматизации выравнивания таблиц.
Спойлер
Вот демонстрация его работы:
[font=courier]
|Г.г.|ст. 158 УК|ст. 162 УК|ст. 161 УК|
|:-|:-:|:-:|:-:|:-:|
|2013|922562|16416|92069|
|2014|908901|14340|77725|
|2015|1018451|13642|72739|
|2016||871084|11416|61524|
|2017|788531|9104|56855|
|2018|756395|7474|50111|
|2019|774159|6739|45815|
[/font]

Стало
[font=courier]
|Г.г.|ст. 158 УК|ст. 162 УК|ст. 161 УК|
|:-  |:-:       |:-:       |:-:       |
|2013|922562    |16416     |92069     |
|2014|908901    |14340     |77725     |
|2015|1018451   |13642     |72739     |
|2016|          |871084    |11416     |
|2017|788531    |9104      |56855     |
|2018|756395    |7474      |50111     |
|2019|774159    |6739      |45815     |
[/font]

Сам скрипт на питоне:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import os
import sys

var=[]

for line in sys.stdin:
    var.append(line[:-1])

# Разбиваем строки на ячейки по разделителю |
var = list(map(lambda x: x.split("|")[1:], var))

col_len = list(map(lambda x: len(x), var[0]))

for str_from_var in var[1:]:
    str_from_var=list(map(lambda x: len(x), str_from_var))
    col_len = list(map(max, zip(str_from_var, col_len)))

out_str='|'
for str_from_var in var:
    str_from_var=list(map(lambda x: x[0].ljust(x[1]," "), zip(str_from_var,col_len)))
    out_str=out_str + "|".join(str_from_var)+"|\n|"

print (out_str[0:-1])

Далее создал пользовательскую команду в geany: python3 /home/user/tab.py
Geany для нее автоматически создает клавиатурное сокращение (у меня ctrl+3). Теперь после выделения текста с заготовкой будущей таблицы нажимаем ctrl+3 - и получаем готовую таблицу. Такие таблицы удобны в просмотре и корректно конвертируются pandoc'ом

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Скрипт форматирования таблиц, дополненный вариант

Предыдущий вариант не правил 2-ю строку ( в которой было  указание о способе выравнивания, мне это было некритично, но выглядело не слишком аккуратно). Сейчас все исправил. Кроме того убираются начальные и конечные пробелы в ячейках таблицы
Спойлер
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys



var=[]

for line in sys.stdin:
    var.append(line[:-1])

# Разбиваем строки на ячейки по разделителю |
var = list(map(lambda x: x.split("|")[1:], var))

for num, line in enumerate(var):
    var[num]=list(map(lambda x: x.strip(), line))
   
col_len = list(map(lambda x: len(x), var[0]))

for str_from_var in var[1:]:
    str_from_var=list(map(lambda x: len(x), str_from_var))
    col_len = list(map(max, zip(str_from_var, col_len)))
   
out_str='|'
for num, str_from_var in enumerate(var):
    if num !=1:
        str_from_var=list(map(lambda x: x[0].ljust(x[1]," "), zip(str_from_var,col_len)))
    else:
        str_from_var=list(map(lambda x: x[0][0:-1].ljust(x[1]-1, "-")+x[0][-1], zip(str_from_var,col_len)))
    out_str=out_str + "|".join(str_from_var)+"|\n|"

print (out_str[0:-1])
« Последнее редактирование: 06.12.2020 16:48:39 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Клавиатурные сокращения в geany

Недавно на форуме https://forum.altlinux.org/index.php?topic=44255.0 появилось решение, как вставлять в текст текущую дату.

В geany это решается просто Например, есть стандартный способ описания ссылок на электронные документы :

Цитировать
Иванов И.И. Название статьи [Электронный ресурс]. URL: https://www.site_name.ru/4147760 (дата обращения 10.12.2020)

В файле snippent.conf (можно его редактировать через меню "Инструменты-Файлы настроек") в секции [markdown] я сделал сниппеты для вставки сносок и для вставки  стандартных фрагментов описания ссылок на электронные ресурсы:

сноска=[^%cursor%]\n\n[^%cursor%]: %cursor%
урл=[Электронный ресурс]. URL: %cursor% (дата обращения: {command:date +"%d.%m.%Y"}).

сноска и урл - это сокращения. Если после этих слов в тексте нажать tab - вставится шаблонный текст. При вставке сниппета "урл" я использовал команду date, которая вставляет в текст текущую дату в нужном мне формате. Использование команды %cursor% позволяет мне перемещаться между местами, куда нужно вставлять мои данные путем нажатия Ctrl+left (или right). Таким же образом можно вставлять в текст результаты любых внешних команд

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Форматирование текста, обновление скрипта для форматирования таблиц

Начертания шрифта в маркдауне задаются обрамляющими звездочками или нижним подчеркиванием:
*курсив* или _курсив_
**жирный**
***жирный курсив*** или _**жирный курсив**_

Для того чтобы обрамлять выделенный текст соответствующими символами сделал однострочный скрипт на питоне:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
sys.stdout.write("**"+"".join(sys.stdin)+"**")

ps Дополнение. А есть способ еще лучше. Если требуется изменить начертание символов в пределах одной строки, то можно создать скрипт bash с одной командой:
#!/bin/bash
sed 's/.*/**&**/'
Если нужно изменить начертание многострочного текста, то лучше использовать скрипт на питоне.
sed обрабатывает тексты построчно и ставит звездочки в начале каждой строки. Т.е. с использованием sed получается больше звездочек, в то время как на питоне - только в начале и в конце выделенного текста.

Далее этот скрипт вешается на клавиатурное сочетание ctrl+и
Аналогично можно сделать для курсива.

Кроме того, по результатам практической эксплуатации усовершенствовал скрипт, форматирующий таблицу.
Последняя версия
Спойлер
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys

#находим ширину колонок
var=[]

for line in sys.stdin:
    var.append(line[:-1])

# Разбиваем строки на ячейки по разделителю |
var = list(map(lambda x: x.split("|")[1:], var))

for num, line in enumerate(var):
    var[num]=list(map(lambda x: x.strip(), line))
   
# Определяем длину ячеек, минимум 3
col_len = list(map(lambda x: len(x), var[0]))

for str_from_var in var[2:]:
    str_from_var=list(map(lambda x: len(x), str_from_var))
    col_len = list(map (lambda x: max(x[0], x[1], 3), zip(str_from_var, col_len)))
   
out_str='|'
for num, str_from_var in enumerate(var):
    if num !=1:
        str_from_var=list(map(lambda x: x[0].ljust(x[1]," "), zip(str_from_var,col_len)))
    else:
        str_from_var=list(map(lambda x: x[0][0]+("-"*(x[1]-2))+x[0][-1], zip(str_from_var,col_len)))
    out_str=out_str + "|".join(str_from_var)+"|\n|"

sys.stdout.write (out_str[0:-1])
« Последнее редактирование: 10.05.2021 15:11:04 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Изменение размера картинок.
В документации по markdown не встречал, а в описании pandoc попадалось про возможность произвольного изменения масштаба вставляемых в текст картинок.

Стандартный синтаксис в маркдауне такой ![РИс1_](p1.png)
Но можно и с указанием размеров по высоте, ширине или только по одному из параметров вс указанием размеров в пикселях или в процентах от исходного. Опытным путем подобрал оптимальную ширину изображения 700 пикселей.

Вот примеры:
1. В пикселях

![Рис1](p1.png "_"){#id .class width=700 height=200px}

только ширина:

![Рис1](p1.png "_"){#id .class width=700px}

2. В процентах:
![Рис1](p1.png "_"){#id .class width=150% height=250%}


Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Очередное усовершенствование скрипта для упорядочивания номеров сносок. Предыдущая версия работала с текстом, в котором в одной строке размещалась одна сноска. Теперь сносок может быть несколько. Основное условие: тексты сносок должны располагаться в той же последовательности, в которой они приводятся в тексте:

Пример текста [^:1], а вот другая сноска [^2]

[^1]:

[^2]:


Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Очередное усовершенствование скрипта для упорядочивания номеров сносок. Предыдущая версия работала с текстом, в котором в одной строке размещалась одна сноска. Теперь сносок может быть несколько. Основное условие: тексты сносок должны располагаться в той же последовательности, в которой они приводятся в тексте:

Пример текста [^:1], а вот другая сноска [^2]

[^1]: Текст сноски

[^2]: Текст другой сноски

В других фрагментах текста, когда вы не помните, какие у вас номера сносок, можно смело опять начинать с 1, скрипт все упорядочит.

Вот текст скрипта:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import sys

# newtext - новое содержание файла
# oldtext - старое содержимое файла

f = open(sys.argv[1], 'r')
oldtext = f.read().splitlines() # список строк из исходного текста
f.close()


newtext=[] # список строк для нового текста
oldstring='' # сюда будем помещать текст очередной строки из исходного текста
newstring='' # а здесь будет преобразованная строка, которую будем помещать в новый текст

notenumer = 0 # это номер сносок в тексте
footnotenumer = 0 # это номер сносок внизу текста

for oldstring in oldtext:
    pos = re.search (r'\[\^\d{0,}\]', oldstring)
    if pos is None:
        newtext.append(oldstring)
    else:
        if pos.start() > 0:
            while pos is not None:
                notenumer = notenumer + 1
                newstring = newstring + oldstring [:pos.start()] +'[^'+str(notenumer)+']'
                oldstring = oldstring[pos.end():]
                pos = re.search (r'\[\^\d{0,}\]', oldstring)
            newstring=newstring+oldstring
        else:
            footnotenumer = footnotenumer+1
            newstring = '[^' +str(footnotenumer) + ']:' + oldstring[pos.end()+1:]
        newtext.append(newstring)
        newstring = ''

f = open(sys.argv[1], 'w')
for newstring in newtext:
    f.write(newstring+'\n')
f.close()
Напомню, что этот скрипт на питоне вызывается особым действием thunar для файлов с расширением md.

В принципе, я свои хотелки в markdown закрыл. Если у кого-инбудь возникнут еще идеи, пишите.

« Последнее редактирование: 20.04.2021 10:55:37 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Еще одно маленькое усовершенствование работы со сносками. В предыдущем варианте для упорядочивания сносок нужно было перейти в thunar, выбрать свой рабочий файл и выполнить для него особое действие, вызывающее скрипт на питоне.

Оказывается, все можно сделать не выходя из geany.
Для этого делаю скрипт ftn.sh следующего содержания:
#!/bin/bash
python3 /home/user/path/footnotes.py "$GEANY_FILENAME"
geany "$GEANY_FILENAME"

В файле /home/user/.config/geany/snippets.conf в разделе Markdown создаем сокращение следующего вида:
ftn={command: /home/user/path/ftn.sh}

Теперь, чтобы упорядочить сноски прямо в тексте, сохраняем файл, затем набираем в любом месте ftn и нажимаем tab. В появившемся меню с предупреждением, что файл на диске изменился, выбираем "Загрузить заново". Все.
« Последнее редактирование: 03.05.2021 12:29:45 от Сергей-70 »

Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Создание презентаций из файлов markdown
При установленном пакете texlive можно делать из md файлов презентации. При этом страницы создается многостраничный pdf со страницами в альбомном формате.

У меня рабочая команда такая:

pandoc --pdf-engine=xelatex -V 'mainfont:Arial' -V 'monofont:Courier New' -t beamer slide.md -o slides-1.pdf

В начале файла md оформляется заголовок:
---
author: И.И. Иванов
title: Пример презентации
institute: НИИЧАВО
theme: AnnArbor
---

В поле theme указывается тема оформления. Варианты тем и их названия можно посмотреть тут https://deic-web.uab.cat/~iblanes/beamer_gallery/index_by_theme.html

Пример простенькой презентации

---
author: И.И. Иванов
title: Пример презентации
institute: НИИЧАВО
theme: AnnArbor
---

# Slide 2

## Коэффициент преступности

$$K =  \frac{P_{pr}\times 100000}{N}$$

значками $

# Slide 2

\includegraphics[width=4in]{1.jpg}

# Slide 3

## Пример текста в две колонки

:::::::::::::: {.columns}
::: {.column}
- Текст, который будет в колонке слева
:::
::: {.column}
- А этот фрагмент будет в колонке справа
:::
::::::::::::::

# Slide 4

`В таких кавычках будет моноширинный текст (кстати это работает и при конвертации в odt)`

А без кавычек - будет простой текст (в команде конвертации у меня указан Arial)


Оффлайн Сергей-70

  • Давно тут
  • **
  • Сообщений: 496
Создание презентаций из файлов markdown
При установленном пакете texlive можно делать из md файлов презентации. При этом страницы создается многостраничный pdf со страницами в альбомном формате.

У меня рабочая команда такая:

pandoc --pdf-engine=xelatex -V 'mainfont:Arial' -V 'monofont:Courier New' -t beamer slide.md -o slides-1.pdf

В начале файла md оформляется заголовок:
---
author: И.И. Иванов
title: Пример презентации
institute: НИИЧАВО
theme: AnnArbor
---

В поле theme указывается тема оформления. Варианты тем и их названия можно посмотреть тут https://deic-web.uab.cat/~iblanes/beamer_gallery/index_by_theme.html

Пример простенькой презентации
Спойлер
---
author: И.И. Иванов
title: Пример презентации
institute: НИИЧАВО
theme: AnnArbor
---

# Slide 2

## Коэффициент преступности

$$K =  \frac{P_{pr}\times 100000}{N}$$

значками $ обрамляется формула

# Slide 2

\includegraphics[width=4in]{1.jpg}

# Slide 3

## Пример текста в две колонки

:::::::::::::: {.columns}
::: {.column}
- Текст, который будет в колонке слева
:::
::: {.column}
- А этот фрагмент будет в колонке справа
:::
::::::::::::::

# Slide 4

`В таких кавычках будет моноширинный текст (кстати это работает и при конвертации в odt)`

А без кавычек - будет простой текст (в команде конвертации у меня указан Arial)


В настоящий момент есть ограничения - вылетает ошибка если в md файле есть таблица. Это вроде бы связано с версией texlive (тут я не очень сведущ, а спросить - не у кого))