LINUX.ORG.RU

Сообщения Xintrea

 

Как в SED обработать диапазон строк?

Есть такой текст:

...
[AC]
icon=battery-charging

[AC][DPMSControl]
idleTime=3600

[AC][HandleButtonEvents]
lidAction=64
powerButtonAction=8

[Battery]
icon=battery-060

[Battery][DPMSControl]
idleTime=300

[Battery][HandleButtonEvents]
lidAction=64
powerButtonAction=16

[LowBattery]
icon=battery-low

[LowBattery][BrightnessControl]
value=30

[LowBattery][HandleButtonEvents]
lidAction=64
powerButtonAction=16
...

Я хочу обработать диапазон строк между:
[AC][HandleButtonEvents]
...
[.*

В этом диапазоне надо изменить значение powerButtonActions.

Я пытаюсь сделать так:
cat f.txt | sed /\[AC\]\[HandleButtonEvents\]/,/\[.*/s/powerButtonAction\s*=\s*.*/powerButtonAction=125/

Но получаю ошибку:

sed: -e выражение #1, символ 81: незавершенное адресное регулярное выражение

Вопрос: как правильно написать эту команду?

 , диапазон

Xintrea
()

Как в Python 2.7.13 изменить INI-файл с субсекциями?

Имеется INI-файл с вот такой структурой:

...
[AC]
icon=battery-charging

[AC][DPMSControl]
idleTime=3600

[AC][HandleButtonEvents]
lidAction=64
powerButtonAction=8

[Battery]
icon=battery-060

[Battery][DPMSControl]
idleTime=300

[Battery][HandleButtonEvents]
lidAction=64
powerButtonAction=16

[LowBattery]
icon=battery-low

[LowBattery][BrightnessControl]
value=30

[LowBattery][HandleButtonEvents]
lidAction=64
powerButtonAction=16
...

Здесь видно, что HandleButtonEvents - это «субсекция», а основная секция задается перед субсекцией в той же строке. Не знаю, является ли это стандартом для INI-файлов или нет, не я этот файл создавал.

Задача - поменять значения powerButtonAction в различных субсукциях.

Пробовал достучаться до нужного значения так (хотя бы считать):
import ConfigParser
config=ConfigParser.ConfigParser()
config.read('$fileName')

print( config.get('AC][HandleButtonEvents', 'powerButtonAction' ) )

Но возникает ошибка:
      "Traceback (most recent call last):",
      "  File \"<stdin>\", line 5, in <module>",
      "  File \"/usr/lib/python2.7/ConfigParser.py\", line 607, in get",
      "    raise NoSectionError(section)",
      "ConfigParser.NoSectionError: No section: 'AC][HandleButtonEvents'"

Вопрос: как работать с такими файлами?

UPD: При необходимости могу поставить Python 3.5.3, если это будет нужно для решения.

 ,

Xintrea
()

Как установить Linux-шрифты в Windows?

Весь интернет забит статьями о том, как установить в Linux шрифты Microsoft и другие популярные Windows-шрифты.

А мне сейчас потребовалось сделать обратное действие: нужно стандартный набор шрифтов, который стоит по-умолчанию в Debian 9, установить в Windows. Как это сделать?

Может быть, есть какие-то LinuxFontPack или еще что-то такое для Windows? Или можно установить пачку шрифтов ручками? Откуда эту пачку взять? Как установить?

 , ,

Xintrea
()

Нужно ли пробрасывать mouseMoveEvent в QTableView?

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

void MyView::mouseMoveEvent(QMouseEvent *event)
{
  ...
  QTableView::mouseMoveEvent(event);
}

Можно ли вообще не делать вызова родительского mouseMoveEvent? На что отсутствие вызова родительского mouseMoveEvent может повлиять?

На первый взгляд действительно, родительский обработчик mouseMoveEvent можно вообще не вызывать. Но может быть, есть какие-то неочевидные ситуации? Например, если не вызывать, то перестанет правильно работать драг-анд-дроп в режиме мультивыбора, или там перестанет выделяться строка при настройке QAbstractItemView::SelectRows после клика мышки на незаполненной строками области таблицы, или еще какая-нибудь замудренная хрэнь?

 , , обработчик,

Xintrea
()

Как выполнить несколько SQL-команд для PostgreSQL в Ansible?

Имеется Astra Linux 1.3, PostgreSQL 9.1.6, Ansible 2.9.16

В инстансе базы данных неожиданно перестали создаваться таблицы.

Создание таблицы приводит к ошибке:

  - name: Create a new database impulse
    postgresql_db:
      name: impulse
      encoding: UTF-8
      lc_collate: ru_RU.UTF-8
      lc_ctype: ru_RU.UTF-8
      owner: impUser
...
FAILED! => 
{"changed": false, 
 "msg": "Database query failed: 
         new encoding (UTF8) is incompatible with the encoding 
         of the template database (SQL_ASCII)\n
         ПОДСКАЗКА:  Use the same encoding as in
         the template database, or use template0 as template.\n"}

Чтобы исправить эту ошибку, необходимо выполнить следующий SQL-скрипт (взят отсюда):
  - name: Исправление кодировки шаблона базы данных
    postgresql_query:
      query: |
        update pg_database set datallowconn = TRUE where datname = 'template0';
        update pg_database set datistemplate = FALSE where datname = 'template1';
        drop database template1;
        create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;
        update pg_database set datistemplate = TRUE where datname = 'template1';
        update pg_database set datallowconn = FALSE where datname = 'template0';

Однако выполнение такого плейбука завершается ошибкой:
FAILED! => {"changed": false, 
"msg": "Cannot execute SQL 'drop database template1;\n
create database template1 with encoding = 'UTF-8' 
lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' 
template = template0;\n'

None: DROP DATABASE cannot run inside a transaction block\n"}

То есть, похоже, что Ansible сама заворачивает выполнение SQL-команд в транзакцию. Я нашел тему, что можно принудительно сначала завершить транзакцию, а потом ее открыть. То есть получится, что сначала выполняется пустая транзакция, потом SQL-команды вне транзакции, и потом опять пустая транзакция:
  - name: Исправление кодировки шаблона базы данных
    postgresql_query:
      query: |
        end; 
        update pg_database set datallowconn = TRUE where datname = 'template0';
        update pg_database set datistemplate = FALSE where datname = 'template1';
        drop database template1;
        create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;
        update pg_database set datistemplate = TRUE where datname = 'template1';
        update pg_database set datallowconn = FALSE where datname = 'template0';
        begin;

Но тогда появляется другая ошибка:
FAILED! => {
"changed": false, 
"msg": "Cannot execute SQL 
'end;\n
update pg_database set datallowconn = TRUE where datname = 'template0';\n
update pg_database set datistemplate = FALSE where datname = 'template1';\n
drop database template1;\n
create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;\n
update pg_database set datistemplate = TRUE where datname = 'template1';\n
update pg_database set datallowconn = FALSE where datname = 'template0';\n
begin;\n' 

None: DROP DATABASE cannot be executed from a function
or multi-command string\n"}

Далее я уже не могу придумать как обходить эти ограничения.

Вопрос: как в Ansible сделать простейшее действие: выполнить несколько SQL-команд?

 , ,

Xintrea
()

Как превратить «узкий неразрывный пробел» E2 80 AF в обычный пробел?

Имеется файл в кодировке UTF-8 с национальными символами, в котором встречаются «узкий неразрывный пробел» с кодами E2 80 AF.

Эти пробелы нужно преобразовать в обычные пробелы.

Как по-быстрому это можно сделать?

 ,

Xintrea
()

Как удобно написать развесистое условие через jinja2 в yml?

В файле all.yml мне надо написать примерно такое:

all:
  vars:
    ...
    targetPath: "{% if   distId=='debian8' %}blablabla1
                 {% elif distId=='debian9' %}blablabla2
                 {% elif distId=='astra13' %}blablabla3
                 {% endif %}|trim()"

Проблема в том, что в таком виде фильтр trim() не работает, потому что ему на вход надо подавать строку. А чтобы обозначить строку, надо выражение {% if ... %} заключить в кавычки. Но в этом коде уже использованы двойные и одинарные кавычки.

Как обойти это ограничение?

 , , ,

Xintrea
()

Сложное вычисление на Python и засовывание результата в Ansible

Нужно мне сделать некоторые вычисления на Python, и результат получить в Ansible.

Делаю так:

  - name: Вычисление суммы
    shell: |
      python <<< "print 1+2"
    register: result

  - debug:
      msg: Результат {{result}}

И при исполнении плейбука ошибка:
fatal: [generatorHost]: FAILED! => {"changed": true, "cmd": "python <<< \"print 1+2\"\n", "delta": "0:00:00.001918", "end": "2020-11-24 15:25:22.719117", "msg": "non-zero return code", "rc": 2, "start": "2020-11-24 15:25:22.717199", "stderr": "/bin/sh: 1: Syntax error: redirection unexpected", "stderr_lines": ["/bin/sh: 1: Syntax error: redirection unexpected"], "stdout": "", "stdout_lines": []}

При этом простое выполнение команды в командной строке работает правильно:
$ python <<< "print 1+2"
3

Как сделать так, чтобы получить значение питоновской команды?

 ,

Xintrea
()

Ansible и Python - как написать условие наличия элемента в списке внутри списка?

В конфигурации Ansible сделан такой список Git-репозитариев:

gitRepos:
- [ "twp.git",                   "master",    "twp",                   "twp.pro" ]
- [ "impulse.git",               "radioline", "calc_impulse",          "impulse.pro" ]
- [ "doxygen_documentation.git", "master",    "doxygen_documentation", "" ]

Как видно, это список (из трех элементов), состоящий из списков (из четырех элементов). На самом деле, список гораздо больше, около 50 записей.

В процессе работы список Git-репозитариев может меняться: в нем постоянно добавляются и удаляются различные строки.

Мне нужно написать такую задачу (task), которая должна проверить наличие строки «doxygen_documentation» в третьем столбце переменной gitRepos, и если такового ни в одной строке нет, завершить работу плейбука:
  - name: Проверка наличия Git-репозитария doxygen_documentation в списке обрабатываемых
    fail: msg="Не подключен репозитарий doxygen_documentation в all.yml"
    when: "<тут какое-то условие проверки gitRepos>"

К сожалению, я не владею Ansible/Питоном настолько, чтобы придумать как сделать такое условие. Как оно должно выглядеть?

 , , ,

Xintrea
()

Как заставить Ansible выводить сообщения об отсутствии переменных?

Есть инвентарь, внутри которого прописаны переменные:

---

all:
  vars:

    variable1: "a10"
    variable2: "b20"
    variable3: "{{ nonVariable }}30"

Видно, что для инициализации переменной variable3 нужно существование переменной nonVariable, но она специально не создана.

Что будет происходить если запустить плейбук с использованием такой переменной?
---
- hosts: all
  tasks:

  - name: Переменная variable1
    debug: var=variable1

  - name: Переменная variable3
    debug: var=variable3

А все будет нормально, просто переменная variable3 будет undefined:
TASK [Переменная variable3] *****
ok: [remoteHost] => {
    "variable3": "VARIABLE IS NOT DEFINED!"
}

То есть, не будет предупреждения, что нет переменной nonVariable, просто не будет определена переменная variable3.

А хотелось бы видеть или предупреждение или причину, по которой variable3 было не определено. Как это можно сделать?

 ,

Xintrea
()

Как в Ansible подключить файл с переменными через конфиг?

Мне нужно использовать несколько «проектов» Ansible, каждый из которых находится в своей директории. Но для этих нескольких «проектов» мне нужно иметь yml-файл с общими переменными.

Я думал, что указать файл с переменными можно в ansible.cfg ( который размещается рядом с плейбуками). Но в документации такой опции не нашел.

Согласно вот этой статье:

https://www.toptechskills.com/ansible-tutorials-courses/ansible-include-impor...

получается, что файл с общими переменными надо прописывать в каждом плейбуке. Но у меня этих плейбуков по 50 штук на каждый проект, не буду же я в каждый плейбук прописывать.

Как-то можно сделать так, чтобы при запуске плейбука он доставал нужный файл с переменными, а не только брал файлы по стандартным путям?

 , ,

Xintrea
()

Хочется странного: кросс-платформенный менеджер буфера обмена через файловую систему

Привет, народ.

Меня тут зажимают по безопасности, и возникла необходимость лютого извращазма.

Итак, в моем распоряжении два компьютера: рабочий с Linux без Интернета, и дополнительный с Windows и Интернетом. Они находятся в физически разных подсетях, но на одном столе. У них есть доступ к файловому серверу, который видится и в Linux, и в Windows. Файловый сервер не под моим контролем, но файлы я могу создавать и с Linux, и с Windows.

В связи с этим вопрос: есть ли какое-то готовое решение, позволяющее в таких условиях организовать хотя бы текстовый буфер обмена между двумя этими машинами?

 

Xintrea
()

Установка 64-битного Microsoft Office в Wine

Системное окружение
-----------------------------------

Операционка: Debian 9 Stable 64 bit
Wine: 5.0.2 из репозитария winehq (deb https://dl.winehq.org/wine-builds/debian/ stretch main)

Нужно установить:

Коробочный Microsoft Office 2010.
Нужно поставить именно 64-х битную версию, т.к. к нему идет закупленный 64-х битный Visio.


Процесс установки
--------------------------------

В /etc/ld.so.conf прописан путь до 64-х битных библиотек, и обновлен кеш через ldconfig:

/opt/wine-stable/lib64

Ставлю офис так:
mkdir ~/.msoffice64
export WINEPREFIX=~/.msoffice64
export WINEARCH=win64
winecfg
./winetricks corefonts allfonts 
./winetricks msxml3 msxml4 msxml6
./winetricks vcrun2005 gdiplus riched30
wine /media/cdrom0/x64/setup.exe

И появляется ошибка: «Язык установочного пакета не поддерживается». В логе установки видно следующее:
...
All OS requirement check passed
Checking if CLSID_DOMDocument60 can be created.
Checking the version of MSXML6.
MSXML version check passed. Minimum required version is [6.10.1129], installed Version is [6.20.2003].
Parsing setup.xml file: D:\x64\Access.ru-ru\setup.xml
Error: Installation of this product requires operating system supplemental language support. Type: 54::NoSupportedCulture.
Error: Installation of this product requires operating system supplemental language support. Type: 54::NoSupportedCulture.
Error: Installation of this product requires operating system supplemental language support. Type: 54::NoSupportedCulture.
Showing parent-less message Title: 'Setup Error', Message: 'Язык установочного пакета не поддерживается.'
Message returned: 1
Catalyst execution finished: 11/10/2020 16:53:56.  Return code: 30054.  Exception caught: NoSupportedCulture.
PERF: TickCount=18528814 Name=RunSetup Description=End function

Как-то можно это исправить?

 , , ,

Xintrea
()

Разрешение доступа к сети в WINE

Имею Debian 9 Stable 64 bit и Wine 5.0.2 из winehq репозитария.

Проблема в том, что внутри Wine недоступен прямой доступ к сети:

$ wine ping linux.org.ru
0009:err:winediag:IcmpCreateFile Failed to use ICMP (network ping), this requires special permissions.
Pinging linux.org.ru [178.248.233.6] with 32 bytes of data:
PING: transmit failed. General failure.
PING: transmit failed. General failure.
PING: transmit failed. General failure.
PING: transmit failed. General failure.

Ping statistics for 178.248.233.6
        Packets: Sent = 4, Received = 0, Lost = 4 (100% loss)

В интернетах пишут, что это потому что не разрешены «возможности» для бинарников wine: https://forum.winehq.org/viewtopic.php?t=31134

Пробую установить возможности доступа к сети. Под рутом даю команды:
setcap cap_net_raw+epi "$(readlink -f "/usr/bin/wine")"
setcap 'cap_net_bind_service=+ep' "$(readlink -f "/usr/bin/wine-preloader")"

Они молча отрабатываются. Но после установки «возможностей», wine перестает находить свои библиотеки:
$ wine
wine: error while loading shared libraries: libwine.so.1: cannot open shared object file: No such file or directory

Если сбросить «возможности»:
setcap -r "$(readlink -f "/usr/bin/wine")"
setcap -r "$(readlink -f "/usr/bin/wine-preloader")"

... то wine опять начинает нормально работать:
$ wine
Usage: wine PROGRAM [ARGUMENTS...]   Run the specified program
       wine --help                   Display this help and exit
       wine --version                Output version information and exit

Но работает, естественно, без доступа к сети.

Независимо от того, установлены «возможности» или нет, библиотека libwine.so.1 видна в ldconfig:
# ldconfig -p | grep libwine
        libwine.so.1 (libc6,x86-64) => /opt/wine-stable/lib64/libwine.so.1
        libwine.so (libc6,x86-64) => /opt/wine-stable/lib64/libwine.so


Вопрос: как заставить wine иметь полный доступ к сети?

 ,

Xintrea
()

Не могу создать ярлык запуска в LXDE

Чтобы запустить bash-скрипт, я создал файл ярлыка:

/home/user/Desktop/connectItcServer.desktop

Содержание:
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=Соединение с ИТЦ
Icon=gparted
Exec=/opt/script/connectItcServer.sh
Terminal=true
Path=/opt/script/
Categories=ConsoleOnly;Utility;

Права на /home/user/Desktop/connectItcServer.desktop - 644
Права на /opt/script/connectItcServer.sh - 755

Однако, при запуске ярлыка, bash-скрипт не выполняется. Вместо этого появляется окно:

Этот текстовый файл «Соединение с ИТЦ», судя по всему является исполняемым скриптом.
Какое действие вы ходите выполнить?
[Выполнить] [Запустить файл в терминале] [Открыть] [Отменить]

Если нажать «Выполнить», то скрипт начнет выполняться.

Но мне нужно, чтобы сразу при запуске ярлыка просто выполнился скрипт.

Это вообще возможно?

 , ,

Xintrea
()

Не вызыватся слот в отдельном потоке (соединение Qt::QueuedConnection)

Имею проект: https://github.com/xintrea/mytetra_dev
Коммит: f3c08a83 (ветка experimental), это просто последний коммит на текущий момент.

У меня есть класс EditorShowTextDispatcher (далее буду называть его просто Dispatcher), который переносится в отдельный поток относительно кода основного приложения. Перенос делается согласно памятке:

Последовательность переноса объекта в отдельный поток для Qt5

Код класса Dispatcher расположен по пути:

/app/src/libraries/wyedit/EditorShowTextDispatcher.cpp

Перенос в отдельный поток происходит в конструкторе данного класса. Перенос осуществляется методом moveToThread(), он вызывается, естественно, ДО настроек коннектов данного класса.

Настройка коннекта для вызова слота класса Dispatcher происходит в классе PeriodicCheckBase:
/app/src/libraries/PeriodicCheckBase.cpp

Настройка коннекта происходит в методе init(). Он вызывается после отработки конструктора класса Dispatcher, то есть после переноса класса Dispatcher в отдельный поток. В коннекте соединяются методы:
c=connect(this, 
          &PeriodicCheckBase::doUpdateDetachedWindows,
          EditorShowTextDispatcher::instance(),
          &EditorShowTextDispatcher::closeWindowForNonExistentRecords,
          Qt::QueuedConnection);

Испускание сигнала doUpdateDetachedWindows() происходит в методе timerEvent() данного класса PeriodicCheckBase.

Создание коннекта происходит успешно, я проверяю результат работы connect(), там все в порядке. В консоль никаких ворнингов в рантайме не сыплется.

Проблема в том, что слот closeWindowForNonExistentRecords() не вызывается.

Если же поменять тип соединения на Qt::DirectConnection, то слот отрабатывает нормально.

Вопрос: где еще что надо докручивать, чтобы слот можено было вызвать в отдельном потоке?

 , , ,

Xintrea
()

Проверка наличия пользователя через getent

Пытаюсь создать пользователей следующим скриптом:

#!/bin/bash

set -xe
echo "> Создание пользователей"
users="user vasya petya operator1 operator2 operator3 operator4"

for userName in $users
do
    echo "Проверка наличия пользователя $userName"

    getent passwd $userName > /dev/null
    if [[ $? -ne 0 ]] ; then
		echo "Создается пользователь $userName"

		# Опция --disabled-login запрещает вход пользователя до тех пор
		# пока не будет задан пароль пользователю
		adduser --disabled-login --gecos "Пользователь-$userName" $userName
    else
		echo "Пользователь уже существует"
    fi
done

В результате, скрипт молча затыкается на пользователе vasya, никаких ошибок не выдает, просто завершает свою работу:
+ echo '> Создание пользователей'
> Создание пользователей
+ users='user vasya petya operator1 operator2 operator3 operator4'
+ for userName in $users
+ echo 'Проверка наличия пользователя user'
Проверка наличия пользователя user
+ getent passwd user
+ [[ 0 -ne 0 ]]
+ echo 'Пользователь уже существует'
Пользователь уже существует
+ for userName in $users
+ echo 'Проверка наличия пользователя vasya'
Проверка наличия пользователя vasya
+ getent passwd vasya


Хоть бы написал «Создается пользователь ...» или «Пользователь уже существует», но этого не происходит.

Что нужно сделать в скрипте, чтобы он заработал как задумано?

 , , ,

Xintrea
()

Странное ключевое слово line в Bash. Это что за?

Если редактировать Bash-скрипты в MC, то можно заметить, что если создать переменную с именем line, то она будет подсвечиваться совсем не так, как другие переменные:

  local fileName=$1 # <-- Эта переменная не подвечивается
  local line=$2 # <-- Здесь line подвечивается голубым цветом

Цвет подсветки совпадает с подсветкой команд, таких как echo или wc. Однако в системе нет утилиты line. И найти в гоголе и яндексе упоминания о такой утилите тоже невозможно. В репозитарии тоже ни одного пакета с утилитой line я не нашел. То есть, мне непонятно, почему MC как-то особенно отображает переменную с таким именем.

Но и это еще не все. Если посмотреть выхлоп скрипта, в котором включена отладка через команду set -xe, то можно увидеть, что механизм задания значения данных переменных отличается:
++ local fileName=/etc/bashrc
++ local 'line=/usr/bin/xset -dpms'

То есть, с переменной с имененм line явно что-то не так. Из-за этого лезут всякие дикие ошибки.

Но я не могу найти, почему в Bash именно переменная с именем line такая особая.

 , line

Xintrea
()

Не могу добавить шаг компиляции - ошибка «Невозможно запустить процесс ...»

Имею QtCreator 4.10.2

Пытаюсь в настройках сборки сделать дополнительный шаг. Нажимаю:

Сборка, добавить этап -> Особый

В поле «Команда» пишу:
echo hello

В результате, при сборке появляется ошибка:
Невозможно запустить процесс «echo hello»

Думал, может там среда выполнения не настроена, попробовал по-всякому:
/bin/echo hello

/bin/bash -c "echo hello"
/bin/bash -c echo hello
bash -c "echo hello"
bash -c echo hello

То же самое, невозможно запустить процесс.

Вопрос: как блин в QtCreator настраивать особый шаг обработки?

 , ,

Xintrea
()

Нумерация в LibreOffice 7.0.0.3

Пытаюсь сделать следующую нумерацию через списки:

1. Первый раздел

1.1 Ананас
1.2 Банан
1.3 Виноград

2. Второй раздел

2.1 Велосипед
...

Так вот, нет никакой возможности в пределах второго раздела сделать пункт Велосипед с номером 2.1.

Вначале в свойствах нумерации выбран вид нумерации:
1.
2.
3.

И выбрана структура нумерации:
1.
1.1.
1.1.1.
1.1.1.1.
...

Во вкладке «Настроить» (в свойствах нумерации) показывается именно такая нумерация, какая нужна:
1.
 1.1.
  1.1.1.
   1.1.1.1.
    ...

Какие номера получается установить для обзаца Велосипед?

Можно сделать номер 3, если выделить абзац Велосипед и выбрать «Продолжить нумерацию».

Можно сделать номер 1, если выделить абзац Велосипед и выбрать «Начать нумерацию заново».

И больше никаких номеров получить невозможно.

Даже если выбрать абзац «1.3 Виноград», нажать «Копировать формат», выбрать абзац Велосипед, то двухномерная нумерация не применится. Вроде как в MS Word этот метод всегда работал безотказно.

Вопрос: как можно добиться нужной нумерации пунктов документа?

 , , ,

Xintrea
()

RSS подписка на новые темы