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
|
# 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
|
# 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.
|
# 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
|
# body = json.loads(input())
|
||||||
import sys
|
# blocks = body['blocks']
|
||||||
import re
|
|
||||||
|
|
||||||
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]
|
# def str2pd(str_to_pandoc):
|
||||||
E, W = "ОШИБКА: ", "ПРЕДУПРЕЖДЕНИЕ: "
|
# def intersperse(lst, item):
|
||||||
SP = [{'t' : 'Space'}]
|
# result = [item] * (len(lst) * 2 - 1)
|
||||||
|
# result[0::2] = lst
|
||||||
unnumbered = True
|
# return result
|
||||||
HEADERSEP = ' '
|
# return intersperse(list(map(
|
||||||
|
# lambda x: {'t': 'Str', 'c': x},
|
||||||
hdlis = [ 'АННОТАЦИЯ', 'ВВЕДЕНИЕ', 'ЗАКЛЮЧЕНИЕ', 'ВЫВОДЫ', 'СПИСОК-ИСПОЛЬЗОВАННЫХ-ИСТОЧНИКОВ' ]
|
# list(filter(lambda x: x != '', re.split('[\t\n\r ]', str_to_pandoc))))),
|
||||||
|
# {'t': 'Space'})
|
||||||
body = json.loads(input())
|
|
||||||
blocks = body['blocks']
|
|
||||||
|
|
||||||
def eprint(*args, **kwargs):
|
|
||||||
print(*args, file=sys.stderr, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def str2pd(str_to_pandoc):
|
# def upper_first_token(tokens):
|
||||||
def intersperse(lst, item):
|
# for token in tokens:
|
||||||
result = [item] * (len(lst) * 2 - 1)
|
# if token['t'] == 'Str':
|
||||||
result[0::2] = lst
|
# token['c'] = token['c'][0].upper() + token['c'][1:]
|
||||||
return result
|
# break
|
||||||
return intersperse(list(map(
|
# return tokens
|
||||||
lambda x: {'t': 'Str', 'c': x},
|
|
||||||
list(filter(lambda x: x != '', re.split('[\t\n\r ]', str_to_pandoc))))),
|
|
||||||
{'t': 'Space'})
|
|
||||||
|
|
||||||
def section_inc (index):
|
# def append_reference (mb_text_block, name, section0, num):
|
||||||
if index <= 1:
|
# if mb_text_block['t'] == 'Div':
|
||||||
global image, formula, table, code
|
# mb_text_block = mb_text_block['c'][-1][0]
|
||||||
image, formula, table, code = 0, 0, 0, 0
|
# if mb_text_block['t'] == 'Para':
|
||||||
global section
|
# for token in mb_text_block['c'][::-1]:
|
||||||
section[index-1] += 1
|
# if token['t'] == 'Str':
|
||||||
section[index:] = [0]*len(section[index:])
|
# token['c'] = token['c'].rstrip('.?!…\t ')
|
||||||
|
# break
|
||||||
|
|
||||||
def section_str (index):
|
# mb_text_block['c'] += [{'t' : 'Space'}] # a space after a paragraph and...
|
||||||
return str(section[0]) if index <= 1 else section_str(index-1)+"."+str(section[index-1])
|
# + upper_first_token(str2pd(f'({name} {section0}.{num}):'))
|
||||||
|
# return True
|
||||||
def phrase_list (phrase, listtype, islast):
|
# return False
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#for i, b in enumerate(blocks):
|
# #for i, b in enumerate(blocks):
|
||||||
i = 0
|
# i = 0
|
||||||
while i < len(blocks):
|
# image, formula, table, code, section = 0, 0, 0, 0, [0, 0, 0]
|
||||||
b = blocks[i]
|
# E, W = "ОШИБКА: ", "ПРЕДУПРЕЖДЕНИЕ: "
|
||||||
|
# while i < len(blocks):
|
||||||
|
# b = blocks[i]
|
||||||
|
# btype = b['t']
|
||||||
|
|
||||||
btype = b['t']
|
# if btype == 'Table':
|
||||||
if btype == 'Header':
|
# if not append_reference(blocks[i-1], 'Таблица', section[0], table):
|
||||||
order = b['c'][0]
|
# eprint(E+"перед таблицей", b['c'],"нет абзаца, в который можно встроить ссылку на таблицу!")
|
||||||
refname = b['c'][1][0]
|
|
||||||
headerTokens = b['c'][2]
|
|
||||||
|
|
||||||
delete_end_marks(headerTokens)
|
|
||||||
|
|
||||||
if btype == 'Header' and order == 1:
|
# blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||||
unnumbered = (refname.strip()).upper() in hdlis
|
|
||||||
if not unnumbered:
|
|
||||||
section_inc(order)
|
|
||||||
headerTokens.insert(0, {'t': 'Str', 'c': str(section_str(order)+HEADERSEP)})
|
|
||||||
|
|
||||||
for token in headerTokens:
|
# if btype == 'Figure':
|
||||||
if token['t'] == 'Str':
|
# if not append_reference(blocks[i-1], 'Рисунок', section[0], image):
|
||||||
token['c'] = token['c'].upper()
|
# eprint(E+"перед рисунком", b['c'], "нет абзаца, в который можно встроить ссылку на рисунок!")
|
||||||
|
|
||||||
if btype == 'Header' and order != 1:
|
# if btype == 'CodeBlock':
|
||||||
if unnumbered:
|
# if len(b['c'][0][2]) == 0:
|
||||||
eprint(E+
|
# eprint(E+"нет подписи у листинга:\n", b['c'][1], "\nЧТОБЫ ДОБАВИТЬ ПОДПИСЬ, используйте ключ caption:\n~~~{.lang caption=\"Hello world\"}")
|
||||||
"Используется заголовок 2 и ниже уровней",
|
|
||||||
b['c'][1],
|
|
||||||
"в ненумерованном разделе (или вовсе вне разделов). \
|
|
||||||
Проверьте структуру разделов.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
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)
|
# code += 1
|
||||||
headerTokens.insert(0, {'t': 'Str', 'c': str(section_str(order)+HEADERSEP)})
|
# 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':
|
# blocks.insert(i, {"t":"Div","c":[["",[],[["custom-style","Code Caption"]]], [{"t":"Para","c":str2pd(caption)}]]})
|
||||||
# if unnumbered:
|
# i += 1
|
||||||
# eprint(E+"Текст или картинка вне раздела \
|
# blocks[i+1] = {'t':'Div', 'c': [["",[],[['custom-style', 'aftertable']]], [blocks[i+1]]]}
|
||||||
# или в ненумерованном разделе",
|
|
||||||
# b['c'][1],
|
|
||||||
# ". Проверьте структуру разделов.")
|
|
||||||
# sys.exit(1)
|
|
||||||
|
|
||||||
for bb in b['c']:
|
# i += 1
|
||||||
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}):')
|
|
||||||
|
|
||||||
if btype == 'Table':
|
# body['blocks'] = blocks
|
||||||
if unnumbered:
|
# print(json.dumps(body))
|
||||||
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))
|
|
||||||
|
|
|
||||||
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: Методика кодирования информации
|
title: Методика кодирования информации
|
||||||
author: Студентов У.M.
|
author: Студентов У.M.
|
||||||
teacher: Беднов Г.А.
|
teacher: Беднов Г.А.
|
||||||
|
type: Курсовая
|
||||||
---
|
---
|
||||||
|
|
||||||
# введение
|
# введение.
|
||||||
<!-- это комментарий Pandoc Markdown. Вы его не увидите -->
|
<!-- это комментарий Pandoc Markdown. Вы его не увидите -->
|
||||||
<!-- кстати, в заголовках первого уровня можно даже писать с маленькой буквы, но только в них -->
|
<!-- кстати, в заголовках первого уровня можно даже писать с маленькой буквы, но только в них. -->
|
||||||
|
<!--знаки препинания на конце удаляются -->
|
||||||
|
|
||||||
Привет мир.
|
Привет мир.
|
||||||
|
|
||||||
# Практическая работа
|
|
||||||
|
|
||||||
Здесь должен быть азбац с текстом
|
|
||||||
|
|
||||||

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

|
||||||
|
|
||||||
Формулы оно тоже *может* поддерживать, но их обязательно надо доделывать!
|
Формулы оно тоже *может* поддерживать, но их обязательно надо доделывать!
|
||||||
|
|
||||||
$$E=mc^2$$
|
$$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