Мой первый пост здесь. Заранее прошу прощения, если случайно нарушу какие-либо правила.
Предположим, что я создал учетную запись службы Google и получил файл учетных данных (JSON). Я создал документ Google, и у меня есть его doc_ID. Мой язык программирования — Python.
Предположим, что у меня есть список элементов смешанного типа, например. (обычный текст, несколько вложенных элементов списка, обычный текст, еще один вложенный элемент списка) и т. д. См. пример ниже:
my_list = [
"This is the normal text line, without any itemized list format.",
"* This is the outermost list item (number)",
"* This is another outermost list item (number)",
" * This is a first-level indented list item (alpha)",
" * This is a second-level indented list item (roman)",
" * This is another second-level indented list item (roman)",
" * This is another first-level indented list item (alpha)",
"This is the normal text line, without any itemized list format.",
"* This is one more outermost list item (number)",
]
Я хочу записать его в документ Google и получить смесь обычного текстового абзаца, за которым следует вложенный нумерованный список с правильными отступами, за которым следует строка обычного текстового абзаца и, наконец, еще один вложенный элемент списка (желательно продолжающий мой предыдущий предустановленной, но и со свежей нумерацией тоже будет приемлемо).
Я попробовал несколько подходов и получил максимально близкий результат, воспользовавшись предложением @tanaike в следующем посте. Как сделать отступ в маркированном списке с помощью API Документов Google
Вот мой пример кода:
text_insert = ""
for text in my_list:
if text.startswith('* '):
text_insert += text[2:] + '\n'
elif text.startswith(' * '):
text_insert += '\t' + text[4:] + '\n'
elif text.startswith(' * '):
text_insert += '\t\t' + text[6:] + '\n'
else:
text_normal = text + '\n'
text_insert += text_normal
end_index_normal = start_index + len(text_insert) + 1 - indent_corr
start_index_normal = end_index_normal - len(text_normal)
end_index = start_index + len(text_insert) + 1
indented_requests = [
{
"insertText": {
"text": text_insert,
'location': {'index': start_index},
}
},
{
"createParagraphBullets": {
'range': {
'startIndex': start_index,
'endIndex': end_index, # Add 2 for the newline character
},
"bulletPreset": "NUMBERED_DECIMAL_ALPHA_ROMAN",
}
},
{
"deleteParagraphBullets": {
'range': {
'startIndex': start_index_normal,
'endIndex': end_index_normal,
},
}
},
]
try:
u_service.documents().batchUpdate(documentId=doc_id, body = {'requests': indented_requests}).execute()
except HttpError as error:
print(f"An error occurred: {error}")
В моем документе Google я получаю следующее:
Однако моя цель следующая (полученная после ручного редактирования):
Как я могу этого добиться? Любая помощь будет оценена.






end_index_normal и start_index_normal перезаписываются другим циклом.deleteParagraphBullets выбирается только один символ.createParagraphBullets.Когда эти моменты будут отражены в вашем сценарии, как насчет следующей модификации?
# Please set your variables.
doc_id = "###"
start_index = 1
indent_corr = 1
my_list = [
"This is the normal text line, without any itemized list format.",
"* This is the outermost list item (number)",
"* This is another outermost list item (number)",
" * This is a first-level indented list item (alpha)",
" * This is a second-level indented list item (roman)",
" * This is another second-level indented list item (roman)",
" * This is another first-level indented list item (alpha)",
"This is the normal text line, without any itemized list format.",
"* This is one more outermost list item (number)",
]
text_insert = ""
deleteParagraphBullets = []
for text in my_list:
if text.startswith('* '):
text_insert += text[2:] + '\n'
elif text.startswith(' * '):
text_insert += '\t' + text[4:] + '\n'
elif text.startswith(' * '):
text_insert += '\t\t' + text[6:] + '\n'
else:
text_normal = text + '\n'
text_insert += text_normal
end_index_normal = start_index + len(text_insert) + 1 - indent_corr
start_index_normal = end_index_normal - len(text_normal)
deleteParagraphBullets.append({
"deleteParagraphBullets": {
'range': {
'startIndex': start_index_normal,
'endIndex': start_index_normal + 1,
},
}
})
deleteParagraphBullets.reverse()
indented_requests = [
{
"insertText": {
"text": text_insert,
'location': {'index': start_index},
}
},
{
"createParagraphBullets": {
'range': {
'startIndex': start_index,
'endIndex': start_index + len(text_insert),
},
"bulletPreset": "NUMBERED_DECIMAL_ALPHA_ROMAN",
}
}
] + deleteParagraphBullets
u_service.documents().batchUpdate(documentId=doc_id, body = {'requests': indented_requests}).execute()
При запуске этого сценария получается следующий результат.
Идеальный! Работает безупречно! Всего один вопрос: Какова цель deleteParagraphBullets.reverse()? Я также попробовал не реверсировать его, и он все равно дает тот же результат. Я хотел бы принять это как ответ, но моя репутация 11 мне не позволяет.
Дополнительный вопрос: этот подход подготавливает одну текстовую строку из всех заданных элементов списка (в настоящее время только двух форматов: элемент списка и обычный текст), а затем подготавливает запрос. Если в списке есть несколько типов элементов, можем ли мы подготовить отдельный запрос для каждого элемента в цикле for, а затем объединить все в конце, чтобы сделать один единственный запрос? Простой первоначальный подход дает нумерацию всех отступов только самыми крайними номерами (без поднумерации).
@Ait Paca О deleteParagraphBullets.reverse(), в случае удаления маркеров, когда оно выполняется в порядке возрастания, индексы других частей изменяются. Итак, я использовал порядок убывания.
@Ait Paca Что касается твоего нового вопроса, я хотел бы тебя поддержать. Но вопрос ответа — это новый вопрос, и он отличается от вашего вопроса. Так можете ли вы опубликовать это как новый вопрос? Потому что, когда ваш первоначальный вопрос изменяется комментарием, другие пользователи, которые видят ваш вопрос, приходят в замешательство. Опубликовав его как новый вопрос, пользователи, включая меня, смогут подумать об этом. Если вы можете помочь решить вашу новую проблему, я буду рад. Можете ли вы сотрудничать, чтобы решить ваш новый вопрос?
Спасибо большое за решение и объяснение. Я принял ваш ответ как правильный (ранее мой комментарий был принят за голосование «за», что мне не разрешено на данном этапе репутации). Я опубликую новый вопрос о конструкции цикла for.
@Ait Paca Спасибо за ответ. Я понимаю вашу текущую ситуацию. И когда я увидел ваш новый вопрос, я хотел бы его проверить. И тебе спасибо.
Большое спасибо! Я только что опубликовал свой вопрос, который доступен по адресу stackoverflow.com/q/78544321/25276165. С нетерпением жду вашего совета/помощи.
@Ait Paca Спасибо за ответ. Я проверю. Если у меня возникнет вопрос, я опубликую его в вашем новом вопросе.
Предупреждение: «Документ Google» = «Кошмар»