lua major update
This commit is contained in:
parent
8eef9b492c
commit
4a0879e81c
7 changed files with 389 additions and 224 deletions
23
.github/workflows/pylint.yml
vendored
23
.github/workflows/pylint.yml
vendored
|
|
@ -1,23 +0,0 @@
|
|||
name: Pylint
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pylint
|
||||
- name: Analysing the code with pylint
|
||||
run: |
|
||||
pylint $(git ls-files '*.py')
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -157,4 +157,5 @@ cython_debug/
|
|||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
.idea/
|
||||
.vscode/
|
||||
|
|
|
|||
20
Readme.md
20
Readme.md
|
|
@ -1 +1,19 @@
|
|||
|
||||
1. Требуется установить Pandoc
|
||||
|
||||
Pandoc - универсальный конвертер документов между различными форматами и разметками.
|
||||
|
||||
2. Для того чтобы воспользоваться скриптом, скачайте репозиторий и введите команду:
|
||||
|
||||
```
|
||||
pandoc --lua-filter=filter2.lua --from markdown --to docx --reference-doc=custom-reference3.docx < отчёт.md > отчёт.docx
|
||||
```
|
||||
|
||||
*Уточнение*. Установка Lua не требуется, так как интерпретатор этого языка программирования "зашит" внутрь Pandoc, хотя сам Pandoc написан на Haskell.
|
||||
|
||||
Программа должна работать в Linux, macOS. По идее, она будет работать и в Windows, но важно сохранить файл .md в кодировке UTF-8.
|
||||
|
||||
3. Есть файл "правила оформления", он частично видоизменен, он неполный, там больший упор на то чего НЕ удалось реализовать в скрипте в автоматическом виде, но на что нужно обратить внимание (odg был создан в libreoffice draw, спокойно конвертируется в PDF).
|
||||
|
||||
__ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ__. Программа является всего лишь ИНСТРУМЕНТОМ, и не заменяет голову на плечах, она предоставляется в том виде, в котором она была создана, она гарантированно многого все ещё *не* умеет (например, пока не придумал способ уместить в pandoc создание титульников)
|
||||
|
||||
Часть первоначальной версии программы доступна в прошлых ревизиях Git и написана на Python. Текущая версия не требует установки Python в систему (и вообще никаких программ, кроме Pandoc), но была переписана на Lua, возможны регрессии функциональности.
|
||||
257
filter.py
257
filter.py
|
|
@ -1,213 +1,82 @@
|
|||
#!/usr/bin/env python3
|
||||
# import json
|
||||
# import sys
|
||||
# import re
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
# body = json.loads(input())
|
||||
# blocks = body['blocks']
|
||||
|
||||
sys.stdin.reconfigure(encoding='utf-8') # for windows
|
||||
# def eprint(*args, **kwargs):
|
||||
# print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
image, formula, table, code, section = 0, 0, 0, 0, [0, 0, 0]
|
||||
E, W = "ОШИБКА: ", "ПРЕДУПРЕЖДЕНИЕ: "
|
||||
SP = [{'t' : 'Space'}]
|
||||
|
||||
unnumbered = True
|
||||
HEADERSEP = ' '
|
||||
|
||||
hdlis = [ 'АННОТАЦИЯ', 'ВВЕДЕНИЕ', 'ЗАКЛЮЧЕНИЕ', 'ВЫВОДЫ', 'СПИСОК-ИСПОЛЬЗОВАННЫХ-ИСТОЧНИКОВ' ]
|
||||
|
||||
body = json.loads(input())
|
||||
blocks = body['blocks']
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
# def str2pd(str_to_pandoc):
|
||||
# def intersperse(lst, item):
|
||||
# result = [item] * (len(lst) * 2 - 1)
|
||||
# result[0::2] = lst
|
||||
# return result
|
||||
# return intersperse(list(map(
|
||||
# lambda x: {'t': 'Str', 'c': x},
|
||||
# list(filter(lambda x: x != '', re.split('[\t\n\r ]', str_to_pandoc))))),
|
||||
# {'t': 'Space'})
|
||||
|
||||
|
||||
def str2pd(str_to_pandoc):
|
||||
def intersperse(lst, item):
|
||||
result = [item] * (len(lst) * 2 - 1)
|
||||
result[0::2] = lst
|
||||
return result
|
||||
return intersperse(list(map(
|
||||
lambda x: {'t': 'Str', 'c': x},
|
||||
list(filter(lambda x: x != '', re.split('[\t\n\r ]', str_to_pandoc))))),
|
||||
{'t': 'Space'})
|
||||
# def upper_first_token(tokens):
|
||||
# for token in tokens:
|
||||
# if token['t'] == 'Str':
|
||||
# token['c'] = token['c'][0].upper() + token['c'][1:]
|
||||
# break
|
||||
# return tokens
|
||||
|
||||
def section_inc (index):
|
||||
if index <= 1:
|
||||
global image, formula, table, code
|
||||
image, formula, table, code = 0, 0, 0, 0
|
||||
global section
|
||||
section[index-1] += 1
|
||||
section[index:] = [0]*len(section[index:])
|
||||
# def append_reference (mb_text_block, name, section0, num):
|
||||
# if mb_text_block['t'] == 'Div':
|
||||
# mb_text_block = mb_text_block['c'][-1][0]
|
||||
# if mb_text_block['t'] == 'Para':
|
||||
# for token in mb_text_block['c'][::-1]:
|
||||
# if token['t'] == 'Str':
|
||||
# token['c'] = token['c'].rstrip('.?!…\t ')
|
||||
# break
|
||||
|
||||
def section_str (index):
|
||||
return str(section[0]) if index <= 1 else section_str(index-1)+"."+str(section[index-1])
|
||||
|
||||
def phrase_list (phrase, listtype, islast):
|
||||
if listtype == 'OrderedList':
|
||||
inl, start = 'в нумерованном списке ', 'большой (заглавной) '
|
||||
else:
|
||||
inl, start = 'в маркированном списке ', 'маленькой (строчной) '
|
||||
endswith = "пункт заканчивается знаком "
|
||||
|
||||
ender, subender = '.', ';'
|
||||
if not islast and listtype != 'OrderedList':
|
||||
ender, subender = subender, ender
|
||||
|
||||
if phrase[0]['t'] == 'Plain':
|
||||
if phrase[0]['c'][0]['c'][0].islower() and (listtype == 'OrderedList'):
|
||||
phrase[0]['c'][0]['c'] = phrase[0]['c'][0]['c'][0].upper() + phrase[0]['c'][0]['c'][1:]
|
||||
if phrase[0]['c'][0]['c'][0].isupper() != (listtype == 'OrderedList'):
|
||||
eprint(W+inl+'текст должен начинаться с ' + start + 'буквы')
|
||||
|
||||
if phrase[0]['c'][-1]['c'][-1] == subender:
|
||||
if islast:
|
||||
eprint(W + inl + "последний " + endswith + ender,
|
||||
", хотя остальных пунктах используется ", subender)
|
||||
else:
|
||||
eprint(W+inl+"каждый" + endswith + ender,
|
||||
" , а не знаком ", subender)
|
||||
elif phrase[0]['c'][-1]['c'][-1] != ender:
|
||||
phrase[0]['c'][-1]['c'] += ender
|
||||
return phrase
|
||||
|
||||
def text_ref (prev, caption, section, figure):
|
||||
return str2pd(f'{caption} {section}.{figure} —') + SP + prev
|
||||
|
||||
def delete_end_marks (tokens, chars='.?!…\t '):
|
||||
for token in tokens[::-1]:
|
||||
if token['t'] == 'Str':
|
||||
token['c'] = token['c'].rstrip(chars)
|
||||
break
|
||||
return tokens
|
||||
|
||||
def upper_first_token(tokens):
|
||||
for token in tokens:
|
||||
if token['t'] == 'Str':
|
||||
token['c'] = token['c'][0].upper() + token['c'][1:]
|
||||
break
|
||||
return tokens
|
||||
|
||||
def append_reference (mb_text_block, name, section0, num):
|
||||
if mb_text_block['t'] == 'Div':
|
||||
mb_text_block = mb_text_block['c'][-1][0]
|
||||
if mb_text_block['t'] == 'Para':
|
||||
delete_end_marks(mb_text_block['c'])
|
||||
mb_text_block['c'] += SP + upper_first_token(str2pd(f'({name} {section0}.{num}):'))
|
||||
return True
|
||||
return False
|
||||
# mb_text_block['c'] += [{'t' : 'Space'}] # a space after a paragraph and...
|
||||
# + upper_first_token(str2pd(f'({name} {section0}.{num}):'))
|
||||
# return True
|
||||
# return False
|
||||
|
||||
|
||||
|
||||
#for i, b in enumerate(blocks):
|
||||
i = 0
|
||||
while i < len(blocks):
|
||||
b = blocks[i]
|
||||
# #for i, b in enumerate(blocks):
|
||||
# i = 0
|
||||
# image, formula, table, code, section = 0, 0, 0, 0, [0, 0, 0]
|
||||
# E, W = "ОШИБКА: ", "ПРЕДУПРЕЖДЕНИЕ: "
|
||||
# while i < len(blocks):
|
||||
# b = blocks[i]
|
||||
# btype = b['t']
|
||||
|
||||
btype = b['t']
|
||||
if btype == 'Header':
|
||||
order = b['c'][0]
|
||||
refname = b['c'][1][0]
|
||||
headerTokens = b['c'][2]
|
||||
|
||||
delete_end_marks(headerTokens)
|
||||
# if btype == 'Table':
|
||||
# if not append_reference(blocks[i-1], 'Таблица', section[0], table):
|
||||
# eprint(E+"перед таблицей", b['c'],"нет абзаца, в который можно встроить ссылку на таблицу!")
|
||||
|
||||
if btype == 'Header' and order == 1:
|
||||
unnumbered = (refname.strip()).upper() in hdlis
|
||||
if not unnumbered:
|
||||
section_inc(order)
|
||||
headerTokens.insert(0, {'t': 'Str', 'c': str(section_str(order)+HEADERSEP)})
|
||||
# blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||
|
||||
for token in headerTokens:
|
||||
if token['t'] == 'Str':
|
||||
token['c'] = token['c'].upper()
|
||||
# if btype == 'Figure':
|
||||
# if not append_reference(blocks[i-1], 'Рисунок', section[0], image):
|
||||
# eprint(E+"перед рисунком", b['c'], "нет абзаца, в который можно встроить ссылку на рисунок!")
|
||||
|
||||
if btype == 'Header' and order != 1:
|
||||
if unnumbered:
|
||||
eprint(E+
|
||||
"Используется заголовок 2 и ниже уровней",
|
||||
b['c'][1],
|
||||
"в ненумерованном разделе (или вовсе вне разделов). \
|
||||
Проверьте структуру разделов.")
|
||||
sys.exit(1)
|
||||
# if btype == 'CodeBlock':
|
||||
# if len(b['c'][0][2]) == 0:
|
||||
# eprint(E+"нет подписи у листинга:\n", b['c'][1], "\nЧТОБЫ ДОБАВИТЬ ПОДПИСЬ, используйте ключ caption:\n~~~{.lang caption=\"Hello world\"}")
|
||||
|
||||
upper_first_token(headerTokens)
|
||||
# if not('caption' in dict(b['c'][0][2])):
|
||||
# eprint(E+"нет подписи у листинга:\n", b['c'][1], "\nЧТОБЫ ДОБАВИТЬ ПОДПИСЬ, используйте ключ caption:\n~~~{.lang caption=\"Hello world\"}")
|
||||
|
||||
section_inc(order)
|
||||
headerTokens.insert(0, {'t': 'Str', 'c': str(section_str(order)+HEADERSEP)})
|
||||
# code += 1
|
||||
# caption = f'Листинг {section[0]}.{code} — ' + dict(b['c'][0][2])['caption']
|
||||
# if not append_reference(blocks[i-1], 'Листинг', section[0], code):
|
||||
# eprint(E+"перед листингом", b['c'], "нет абзаца, в который можно встроить ссылку на листинг!")
|
||||
|
||||
if btype == 'Para':
|
||||
# if unnumbered:
|
||||
# eprint(E+"Текст или картинка вне раздела \
|
||||
# или в ненумерованном разделе",
|
||||
# b['c'][1],
|
||||
# ". Проверьте структуру разделов.")
|
||||
# sys.exit(1)
|
||||
# blocks.insert(i, {"t":"Div","c":[["",[],[["custom-style","Code Caption"]]], [{"t":"Para","c":str2pd(caption)}]]})
|
||||
# i += 1
|
||||
# blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||
|
||||
for bb in b['c']:
|
||||
bbtype = bb['t']
|
||||
if bbtype == 'Image':
|
||||
image += 1
|
||||
b['c'][0]['c'][1] = text_ref(b['c'][0]['c'][1], 'Рисунок', section[0], image) # TODO error if fail
|
||||
delete_end_marks(blocks[i-1]['c'])
|
||||
blocks[i-1]['c'] += SP + str2pd(f'(Рисунок {section[0]}.{image}):')
|
||||
# i += 1
|
||||
|
||||
if btype == 'Table':
|
||||
if unnumbered:
|
||||
eprint(E+"Таблица вне раздела или в ненумерованном разделе:\n", b['c'], "\nПровертье структуру разделов.")
|
||||
sys.exit(1)
|
||||
table += 1
|
||||
b['c'][1][1][0]['c'] = str2pd(f'Таблица {section[0]}.{table} —') + SP + b['c'][1][1][0]['c']
|
||||
if not append_reference(blocks[i-1], 'Таблица', section[0], table):
|
||||
eprint(E+"перед таблицей", b['c'],"нет абзаца, в который можно встроить ссылку на таблицу!")
|
||||
sys.exit(1)
|
||||
|
||||
blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||
|
||||
if btype == 'Figure':
|
||||
if unnumbered:
|
||||
eprint(E+"Рисунок вне раздела или в ненумерованном разделе:\n", b['c'], "\nПровертье структуру разделов.")
|
||||
sys.exit(1)
|
||||
image += 1
|
||||
b['c'][1][1][0]['c'] = str2pd(f'Рисунок {section[0]}.{image} —') + SP + b['c'][1][1][0]['c']
|
||||
|
||||
if not append_reference(blocks[i-1], 'Рисунок', section[0], image):
|
||||
eprint(E+"перед рисунком", b['c'], "нет абзаца, в который можно встроить ссылку на рисунок!")
|
||||
sys.exit(1)
|
||||
|
||||
if btype == 'CodeBlock':
|
||||
if unnumbered:
|
||||
eprint(E+"Листинг вне раздела или в ненумерованном разделе:\n", b['c'], "\nПровертье структуру разделов.")
|
||||
sys.exit(1)
|
||||
if len(b['c'][0][2]) == 0:
|
||||
eprint(E+"нет подписи у листинга:\n", b['c'][1], "\nЧТОБЫ ДОБАВИТЬ ПОДПИСЬ, используйте ключ caption:\n~~~{.lang caption=\"Hello world\"}")
|
||||
sys.exit(1)
|
||||
|
||||
if not('caption' in dict(b['c'][0][2])):
|
||||
eprint(E+"нет подписи у листинга:\n", b['c'][1], "\nЧТОБЫ ДОБАВИТЬ ПОДПИСЬ, используйте ключ caption:\n~~~{.lang caption=\"Hello world\"}")
|
||||
sys.exit(1)
|
||||
|
||||
code += 1
|
||||
caption = f'Листинг {section[0]}.{code} — ' + dict(b['c'][0][2])['caption']
|
||||
if not append_reference(blocks[i-1], 'Листинг', section[0], code):
|
||||
eprint(E+"перед листингом", b['c'], "нет абзаца, в который можно встроить ссылку на листинг!")
|
||||
sys.exit(1)
|
||||
|
||||
blocks.insert(i, {"t":"Div","c":[["",[],[["custom-style","Code Caption"]]], [{"t":"Para","c":str2pd(caption)}]]})
|
||||
i += 1
|
||||
blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||
# eprint(blocks[i+1])
|
||||
# .insert(i, {"t":"Div","c":[["",[],[["custom-style","Code Caption"]]], [{"t":"Para","c":str2pd(caption)}]]})
|
||||
|
||||
if btype == 'BulletList':
|
||||
for j, phrase in enumerate(b['c']):
|
||||
phrase = phrase_list(phrase, btype, j == (len(b['c']) - 1))
|
||||
|
||||
if btype == 'OrderedList':
|
||||
for phrase in b['c'][1]:
|
||||
phrase = phrase_list(phrase, btype, False)
|
||||
|
||||
i += 1
|
||||
|
||||
body['blocks'] = blocks
|
||||
print(json.dumps(body))
|
||||
# body['blocks'] = blocks
|
||||
# print(json.dumps(body))
|
||||
|
|
|
|||
267
filter2.lua
Normal file
267
filter2.lua
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
IMAGE, FORMULA, TABLE, CODE = 0, 0, 0, 0
|
||||
UNNUMBERED = true
|
||||
local hdlis = {
|
||||
['АННОТАЦИЯ'] = true,
|
||||
['ВВЕДЕНИЕ'] = true,
|
||||
['ЗАКЛЮЧЕНИЕ'] = true,
|
||||
['ВЫВОДЫ'] = true,
|
||||
['СПИСОК-ИСПОЛЬЗОВАННЫХ-ИСТОЧНИКОВ'] = true
|
||||
}
|
||||
|
||||
local section = {0, 0, 0}
|
||||
|
||||
local function remove_trailing_punctuation(text)
|
||||
return text:gsub("[,;%.!?]+$", "")
|
||||
end
|
||||
|
||||
local function capitalize_first_letter(text)
|
||||
local first_char = pandoc.text.sub(text, 1, 1)
|
||||
local rest = pandoc.text.sub(text, 2)
|
||||
return pandoc.text.upper(first_char) .. rest
|
||||
end
|
||||
|
||||
local function is_unnumbered(header_text)
|
||||
return hdlis[pandoc.text.upper(header_text)] ~= nil
|
||||
end
|
||||
|
||||
local function get_section_number(level)
|
||||
if level == 1 then
|
||||
section[1] = section[1] + 1
|
||||
section[2] = 0
|
||||
section[3] = 0
|
||||
IMAGE = 0
|
||||
|
||||
return tostring(section[1])
|
||||
elseif level == 2 then
|
||||
if section[1] == 0 then
|
||||
io.stderr:write("Ошибка: Второй уровень без первого запрещен\n")
|
||||
return nil
|
||||
end
|
||||
section[2] = section[2] + 1
|
||||
section[3] = 0
|
||||
return section[1] .. "." .. section[2]
|
||||
elseif level >= 3 then
|
||||
if section[1] == 0 or section[2] == 0 then
|
||||
io.stderr:write("Ошибка: Третий уровень без первого или второго запрещен\n")
|
||||
return nil
|
||||
end
|
||||
section[3] = section[3] + 1
|
||||
return section[1] .. "." .. section[2] .. "." .. section[3]
|
||||
end
|
||||
end
|
||||
|
||||
function Header(el)
|
||||
local cleaned_text = capitalize_first_letter(remove_trailing_punctuation(pandoc.utils.stringify(el.content)))
|
||||
local is_unnumbered_section = is_unnumbered(cleaned_text)
|
||||
UNNUMBERED = is_unnumbered_section
|
||||
local level = math.min(el.level, 3) -- Принудительно ограничиваем вложенность до 3
|
||||
|
||||
if level > 1 and section[1] == 0 then
|
||||
io.stderr:write("Ошибка: Заголовки 2 и ниже без нумерованного заголовка 1 уровня\n")
|
||||
return el
|
||||
end
|
||||
|
||||
if not is_unnumbered_section then
|
||||
local section_number = get_section_number(level)
|
||||
cleaned_text = section_number .. " " .. capitalize_first_letter(cleaned_text)
|
||||
elseif level > 1 then
|
||||
io.stderr:write("Ошибка: В ненумеруемом разделе не должно быть вложенных заголовков\n")
|
||||
return el
|
||||
end
|
||||
|
||||
el.content = pandoc.Inlines(cleaned_text)
|
||||
return el
|
||||
end
|
||||
|
||||
|
||||
|
||||
function Figure(el)
|
||||
IMAGE = IMAGE + 1
|
||||
local str = pandoc.utils.stringify(el.caption)
|
||||
str = capitalize_first_letter(str)
|
||||
str = remove_trailing_punctuation(str)
|
||||
if UNNUMBERED then
|
||||
io.stderr:write("Ошибка: Рисунок " .. str .. " в ненумерованном разделе!")
|
||||
return el
|
||||
end
|
||||
str = "Рисунок " .. section[1] .. "." .. IMAGE .. " — " .. str
|
||||
|
||||
el.caption = pandoc.Blocks(str)
|
||||
return el
|
||||
end
|
||||
|
||||
function Table(el)
|
||||
TABLE = TABLE + 1
|
||||
local str = pandoc.utils.stringify(el.caption)
|
||||
str = capitalize_first_letter(str)
|
||||
str = remove_trailing_punctuation(str)
|
||||
if UNNUMBERED then
|
||||
io.stderr:write("Ошибка: Таблица " .. str .. " в ненумерованном разделе!")
|
||||
return el
|
||||
end
|
||||
str = "Таблица " .. section[1] .. "." .. IMAGE .. " — " .. str
|
||||
el.caption = pandoc.Blocks(str)
|
||||
return el
|
||||
end
|
||||
|
||||
--[[
|
||||
Предполагается, что ранее в фильтре уже определены:
|
||||
IMAGE, FORMULA, TABLE, CODE = 0, 0, 0, 0
|
||||
UNNUMBERED, hdlis, section
|
||||
функции Header, Figure, Table (обрабатывающие подписи и прочее)
|
||||
Этот блок добавляет модификацию соседних блоков (предыдущего Para для ссылки,
|
||||
а также оборачивание следующего блока для Table и CodeBlock).
|
||||
--]]
|
||||
|
||||
-- Функция для приведения первой буквы строки к заглавной
|
||||
function capitalize_first_letter(text)
|
||||
local first = pandoc.text.sub(text, 1, 1)
|
||||
local rest = pandoc.text.sub(text, 2)
|
||||
return pandoc.text.upper(first) .. rest
|
||||
end
|
||||
|
||||
-- Функция оборачивает блок в Div с кастомным стилем "aftertable"
|
||||
function wrap_aftertable(block)
|
||||
return pandoc.Div(block, pandoc.Attr("", {}, {["custom-style"] = "aftertable"}))
|
||||
end
|
||||
|
||||
-- Функция, которая ищет в списке блоков блок по индексу index и, если это Para (или вложенный Para в Div),
|
||||
-- удаляет завершающую пунктуацию у последнего текстового элемента и дописывает ссылку в виде:
|
||||
-- " (Тип section.num):"
|
||||
function append_reference_to_block(blocks, index, ref_name, section_num, num)
|
||||
if index < 1 or index > #blocks then
|
||||
return false
|
||||
end
|
||||
local blk = blocks[index]
|
||||
-- Если блок – Div, пробуем взять последний вложенный блок из его содержимого
|
||||
if blk.t == "Div" then
|
||||
if blk.c and #blk.c >= 2 and type(blk.c[2]) == "table" and #blk.c[2] > 0 then
|
||||
blk = blk.c[2][#blk.c[2]]
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
if blk.t ~= "Para" then
|
||||
return false
|
||||
end
|
||||
-- Удаляем завершающую пунктуацию у последнего Str
|
||||
local inlines = blk.c
|
||||
for j = #inlines, 1, -1 do
|
||||
if inlines[j].t == "Str" then
|
||||
inlines[j].text = inlines[j].text:gsub("[%.?!…%s]+$", "")
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Формируем текст ссылки, например: "(Рисунок 1.2):"
|
||||
local ref_text = "(" .. ref_name .. " " .. section_num .. "." .. num .. "):"
|
||||
ref_text = capitalize_first_letter(ref_text)
|
||||
table.insert(inlines, pandoc.Space())
|
||||
table.insert(inlines, pandoc.Str(ref_text))
|
||||
return true
|
||||
end
|
||||
|
||||
-- Главная функция фильтра, которая проходит по всем блокам документа и в нужных местах
|
||||
-- модифицирует соседние блоки.
|
||||
function Pandoc(doc)
|
||||
local blocks = doc.blocks
|
||||
local i = 1
|
||||
while i <= #blocks do
|
||||
local blk = blocks[i]
|
||||
if blk.t == "Table" then
|
||||
-- Для таблиц: добавляем ссылку в предыдущий абзац и оборачиваем следующий блок
|
||||
if not append_reference_to_block(blocks, i - 1, "Таблица", section[1], TABLE) then
|
||||
io.stderr:write("ОШИБКА: перед таблицей нет абзаца для ссылки\n")
|
||||
end
|
||||
if i + 1 <= #blocks then
|
||||
blocks[i + 1] = wrap_aftertable(blocks[i + 1])
|
||||
end
|
||||
elseif blk.t == "Figure" then
|
||||
-- Для рисунков: добавляем ссылку в предыдущий абзац
|
||||
if not append_reference_to_block(blocks, i - 1, "Рисунок", section[1], IMAGE) then
|
||||
io.stderr:write("ОШИБКА: перед рисунком нет абзаца для ссылки\n")
|
||||
end
|
||||
elseif blk.t == "CodeBlock" then
|
||||
-- Для листингов: проверяем наличие подписи (caption) в атрибутах
|
||||
local attr = blk.attr or {"", {}, {}}
|
||||
local attributes = attr[3] or {}
|
||||
local caption = attributes.caption
|
||||
if not caption then
|
||||
io.stderr:write("ОШИБКА: Листинг без подписи!\nИспользуйте ключ caption в CodeBlock\n")
|
||||
else
|
||||
CODE = CODE + 1
|
||||
local ref_text = "Листинг " .. section[1] .. "." .. CODE .. " — " .. caption
|
||||
if not append_reference_to_block(blocks, i - 1, "Листинг", section[1], CODE) then
|
||||
io.stderr:write("ОШИБКА: перед листингом нет абзаца для ссылки\n")
|
||||
end
|
||||
-- Вставляем блок с подписью перед текущим CodeBlock.
|
||||
local caption_block = pandoc.Div(
|
||||
pandoc.Para({ pandoc.Str(capitalize_first_letter(ref_text)) }),
|
||||
pandoc.Attr("", {}, {["custom-style"] = "Code Caption"})
|
||||
)
|
||||
table.insert(blocks, i, caption_block)
|
||||
i = i + 1 -- пропускаем вставленный блок
|
||||
if i + 1 <= #blocks then
|
||||
blocks[i + 1] = wrap_aftertable(blocks[i + 1])
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
return pandoc.Pandoc(blocks, doc.meta)
|
||||
end
|
||||
|
||||
function Meta(m)
|
||||
if m.date == nil then
|
||||
m.date = os.date("%e «%m» %Y")
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
local function remove_trailing_punctuation_li (li)
|
||||
return pandoc.Blocks(remove_trailing_punctuation(pandoc.utils.stringify(li)))
|
||||
end
|
||||
|
||||
local function add_trailing_semicolon_li (li)
|
||||
return pandoc.Blocks(pandoc.utils.stringify(li) .. ";")
|
||||
end
|
||||
|
||||
local function add_trailing_stop_li (li)
|
||||
return pandoc.Blocks(pandoc.utils.stringify(li) .. ".")
|
||||
end
|
||||
|
||||
local function capitalize_first_letter_li (li)
|
||||
return pandoc.Blocks(capitalize_first_letter(pandoc.utils.stringify(li)))
|
||||
end
|
||||
|
||||
local function warnCapitalizedStart (li)
|
||||
local str = pandoc.utils.stringify(li)
|
||||
local capitalized = capitalize_first_letter(str)
|
||||
if str == capitalized
|
||||
then
|
||||
io.stderr:write("Предупреждение: необходимо исправить вручную. В маркированном списке предложение должно начинаться со строчной (маленькой) буквы. Если текст пункта стартует с аббревиатуры, проигнорируйте данное предупреждение, иначе - исправьте вручную. Текст пункта:\n" .. str)
|
||||
end
|
||||
|
||||
return li
|
||||
end
|
||||
|
||||
function BulletList(el)
|
||||
local li = el.content
|
||||
li = pandoc.List.map(li, remove_trailing_punctuation_li)
|
||||
li = pandoc.List.map(li, add_trailing_semicolon_li)
|
||||
local ending = pandoc.List.at(el.content, -1)
|
||||
pandoc.List.remove(li)
|
||||
ending = add_trailing_stop_li(remove_trailing_punctuation_li(ending))
|
||||
pandoc.List.insert(li, ending)
|
||||
li = pandoc.List.map(li, warnCapitalizedStart);
|
||||
el.content = li
|
||||
return el
|
||||
end
|
||||
|
||||
function OrderedList(el)
|
||||
local li = el.content
|
||||
li = pandoc.List.map(li, remove_trailing_punctuation_li)
|
||||
li = pandoc.List.map(li, add_trailing_stop_li)
|
||||
li = pandoc.List.map(li, capitalize_first_letter_li)
|
||||
el.content = li
|
||||
return el
|
||||
end
|
||||
BIN
отчёт.docx
Normal file
BIN
отчёт.docx
Normal file
Binary file not shown.
43
отчёт.md
43
отчёт.md
|
|
@ -2,21 +2,54 @@
|
|||
title: Методика кодирования информации
|
||||
author: Студентов У.M.
|
||||
teacher: Беднов Г.А.
|
||||
type: Курсовая
|
||||
---
|
||||
|
||||
# введение
|
||||
# введение.
|
||||
<!-- это комментарий Pandoc Markdown. Вы его не увидите -->
|
||||
<!-- кстати, в заголовках первого уровня можно даже писать с маленькой буквы, но только в них -->
|
||||
<!-- кстати, в заголовках первого уровня можно даже писать с маленькой буквы, но только в них. -->
|
||||
<!--знаки препинания на конце удаляются -->
|
||||
|
||||
Привет мир.
|
||||
|
||||
# Практическая работа
|
||||
|
||||
Здесь должен быть азбац с текстом
|
||||
|
||||

|
||||
# практическая работа!
|
||||
## очень маленький заголовок
|
||||
|
||||
|
||||
## подраздельчик
|
||||
|
||||
1. f
|
||||
1. 2
|
||||
1. 2
|
||||
1. 4
|
||||
|
||||
* Ф;
|
||||
* b,
|
||||
|
||||
Здесь обязан быть абзац с текстом, так как он предваряет картинку
|
||||
|
||||

|
||||
|
||||
Формулы оно тоже *может* поддерживать, но их обязательно надо доделывать!
|
||||
|
||||
$$E=mc^2$$
|
||||
|
||||
: пример таблички
|
||||
|
||||
Right Left Center Default
|
||||
------- ------ ---------- -------
|
||||
12 12 12 12
|
||||
123 123 123 123
|
||||
1 1 1 1
|
||||
|
||||
|
||||
```cpp
|
||||
|
||||
int main(void) {
|
||||
std::cout << "Hello world";
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue