手记

用Python实现Markdown转Google文档的小工具

使用文档API的快速入门... 本文概要:

其他 Google Workspace (GWS) API 相关的博客文章似乎都是关于 Docs & Sheets(也就是它们的 API),但代码示例几乎总是文件操作,例如将 Google 文档导出为 PDF 文件将 CSV 文件导入 Google 表格中。文件操作通常与 Google Drive API 相关,而不是“编辑器”API。而这篇博客文章则打破了这种模式,启动了一个将 Markdown 转换为 Google 文档的转换器;是的,使用的是 Docs(而不是 Drive)API!通过这篇文章,读者将学到如何通过编程方式创建新的 Google 文档,并向其中写入和格式化文本

(点击图片查看)

介绍与动机阐述

你发现了一个专注于向 Python(和有时是 Node.js)开发者展示如何使用 Google 开发者生态系统的不同部分(从 API 到计算和 AI/ML 平台)的博客,在这里我提供像润滑油一样的帮助来帮助你减少入门时的阻力。无论你对哪个主题感兴趣,我基本上都能帮到你:

我对大部分的 GWS 内容都感到有点“不满”:它们 仅仅覆盖了 Drive API。太无聊了!Workspace 有那么多其他 API,如果我不去探索 另一个 GWS API,对你们来说都没有好处。所以今天我就选了 Google Docs API

灵感和动力的应用

这个示例应用受到了两个熟悉项目的启发。之前,我创建了一个工具,该工具可以导入并解析类似Markdown语法的演示文稿大纲,并将其转换成Microsoft PowerPoint演示文稿。你甚至可以设置模板并启动幻灯片演示!紧接着,为Microsoft Word、Excel和Outlook开发了其他脚本,并在我的一本Python书中(详见第七章“编程Microsoft Office”)有所介绍。(对粉丝和读者来说:是的,我知道我需要更新这个版本,并把代码上传到GitHub上吧!)

在 Google Slides API 发布之后,我希望能够为 Slides 创建一个类似的工具,然而一位同事抢先一步用 md2googleslides 实现了一个类似工具,该项目支持完整的 Markdown 和多种内容,广受好评并被大量星标。这样一个大型工具对于像这样的简短内容来说会显得过于复杂,所以我选择了最基本的 Markdown 子集,仅支持下划线(_)用于斜体和星号(*)用于加粗:

使用任何这些指令格式化的文件,从 Markdown 中提取文本,创建一个 Google 文档,插入文本,然后按照标记指令格式化。(其他版本的 Markdown 或维基标记使用单个符号(两者之一)表示斜体,双符号表示加粗,但我为了简化正则表达式选择了更简单的实现方式。)

虽然你可以使用 Google 文档中的 Markdown 编辑功能以及 导入和导出 Markdown 文件,但如果你需要处理成百上千个生成的 Markdown 文件,你不会希望手动通过用户界面来处理这么多文件。要真正实现自动化,而不仅仅是一次处理一个文件,你需要 API 的力量来实现这个目标。

📝 注意:备选版本使用较旧的 Python(OAuth2)认证库


在这篇文章中有一个应用的备选版本:主脚本使用的是当前的 Python Google 认证库,而备选版本(名为 *-old.py)则使用 较旧的认证库,该库虽然自2017年起已被弃用,但仍然被广泛使用(而且遗憾的是,在许多在线示例中也是如此)。它作为一个迁移工具,帮助仍在使用旧版本的用户进行升级。

📝 注意:代码示例兼容 Python 2 和 3


为了帮助 Python 2 用户升级和迁移至 Python 3,这些示例脚本兼容 Python 2.x 和 3.x。然而,这意味着您不会找到仅属于 Python 3 的特性,比如 f-string、类型注解或 asyncawait。如果读者愿意提交一个纯 Python 3 版本,我很欢迎相关的 PR 请求。

代码

这个应用有四个版本,Python和Node.js各有两个版本的实现,所有这些都在代码库的repo文件夹中可以访问。代码库的repo文件夹链接为:

导入

[md2docs.py](https://github.com/wescpy/google/tree/main/apps/md2docs/python/md2docs.py) 这个导入代码如下:

Python

    from __future__ import print_function
    import os.path
    import re

    from google.auth.transport.requests import Request
    from google.oauth2 import credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient import discovery

进入全屏 退出全屏

标准库导入使 Python 3 的 print() 函数可以在 Python 2 中使用(在 Python 3.x 中不再使用),通过 os 模块访问文件系统,并通过 re 模块处理正则表达式。接着导入 Google API 和认证客户端库。

对于仍然使用旧版认证库的开发人员,这里有一些在 md2docs-old.py 文件中的等效导入语句:

    from __future__ import print_function
    import re

    from googleapiclient import discovery
    from httplib2 import Http
    from oauth2client import file, client, tools

按这儿切换全屏

JavaScript(一种编程语言)
来看 JavaScript,以下是针对 Node.js ES 模块的等效代码示例,该代码位于此链接:md2docs.mjs

    import fs from 'node:fs/promises';
    import path from 'node:path';
    import process from 'node:process';
    import { authenticate } from '@google-cloud/local-auth';
    import { google } from 'googleapis';

全屏模式(按 Esc 退出)

如果你更喜欢 CommonJS,那么文件是md2docs.js,而这些代码片段看起来像这样。

const fs = require('fs').promises;
const path = require('path');
const process = require('process');
const { authenticate } = require('@google-cloud/local-auth');
const { google } = require('googleapis');

你可以看到,这些代码行是用来引入并使用Node.js的几个核心模块的。

全屏 退出全屏

就像他们的 Python 双胞胎一样,这些包也使用了文件系统操作包以及 Google 安全和 API 访问。这里就是这两个 JavaScript 版本之间的差异,其余代码都是相同的,无论是 ES 模块还是 CommonJS。

安全:

接下来是常量和验证码:

Python (一种编程语言)

    FILENAME = 'quickbrownfox.md'  # 将此更改为自己的 Markdown 文件

    creds = None
    SCOPES = 'https://www.googleapis.com/auth/documents'
    TOKENS = 'storage.json'
    if os.path.exists(TOKENS):
        creds = credentials.Credentials.from_authorized_user_file(TOKENS)
    if creds is None or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('client_secret.json', SCOPES)
            creds = flow.run_local_server()
    with open(TOKENS, 'w') as token:
        token.write(creds.to_json())
    DOCS = discovery.build('docs', 'v1', credentials=creds)

全屏模式 退出全屏

旧版本的认证使用起来更简单,因为该库管理OAuth令牌的存储(因此无需自己管理)。

    FILENAME = 'quickbrownfox.md'  # 请将其替换为你自己的 Markdown 文件

    SCOPES = 'https://www.googleapis.com/auth/documents'
    store = file.Storage('storage.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
        creds = tools.run_flow(flow, store)
    DOCS = discovery.build('docs', 'v1', http=creds.authorize(Http()))
    # 用于操作 Google 文档的 API 对象

全屏显示 退出全屏

除此之外,两个 Python 版本是相同的。JavaScript 代码的工作方式与 Python 类似,但略有不同之处:每个功能都被拆分并分配到单独的函数中,并改进了常量和命名约定:

JavaScript

    const FILENAME = 'quickbrownfox.md';  // 请将此改为你的 Markdown 文件名
    const CREDENTIALS_PATH = path.join(process.cwd(), 'client_secret.json');
    const TOKEN_STORE_PATH = path.join(process.cwd(), 'storage.json');
    const SCOPES = [ 'https://www.googleapis.com/auth/documents' ];

    async function loadSavedCredentialsIfExist() {
      try {
        const content = await fs.readFile(TOKEN_STORE_PATH);
        // 从 TOKEN_STORE_PATH 读取内容并将其存储为 content 变量
        const credentials = JSON.parse(content);
        return google.auth.fromJSON(credentials);
      } catch (err) {
        return null;
      }
    }

    async function saveCredentials(client) {
      const content = await fs.readFile(CREDENTIALS_PATH);
      const keys = JSON.parse(content);
      const key = keys.installed || keys.web;
      const payload = JSON.stringify({
        type: 'authorized_user',
        client_id: key.client_id,
        client_secret: key.client_secret,
        refresh_token: client.credentials.refresh_token,
        access_token: client.credentials.access_token,
        token_expiry: client.credentials.token_expiry,
        scopes: client.credentials.scopes,
      });
      // 将凭据保存至 TOKEN_STORE_PATH 文件
      await fs.writeFile(TOKEN_STORE_PATH, payload);
    }

    async function authorize() {
      var client = await loadSavedCredentialsIfExist();
      if (client) return client;
      client = await authenticate({
        scopes: SCOPES,
        keyfilePath: CREDENTIALS_PATH,
      });
      // 如果有凭证,将凭证保存至 TOKEN_STORE_PATH
      if (client.credentials) await saveCredentials(client);
      return client;
    }

全屏切换

顶部的指针指向了quickbrownfox.md数据文件,但其内容是随意的。你可以随意更改内容,或者将代码指向你自己的Markdown文件。为了演示,这里提供的quickbrownfox.md文件包含如下Markdown数据:

那只快速的棕色狐狸跳过了那几只懒狗。

点击全屏,退出全屏

安全码是必需的,因为最终用户必须授予你的代码访问他们的数据的权限;在这种情况下,是代表他们创建文档。("authz")授权要求你创建一个客户端ID和密钥对,然后从你的Google开发者项目下载文件。

有关这段代码的详细信息以及如何为GWS API进行“认证”的操作可以在 OAuth客户端ID三部曲(主要是最后一篇文章)中找到,所以这里就不赘述了。如果你是新手或需要复习相关知识,请查看这些文章。在代码审查之后,我会提供运行示例所需的设置步骤,但请参阅这些文章获取所有相关细节。

Python 安全代码片段以 DOCS 结束,DOCS 是一个 Docs API 客户端对象,用于 Docs API 调用的服务端点。(在许多官方 Google 代码示例中,不是描述性的常量 DOCS,而你会看到使用 service 作为变量名,现在你知道为什么了。)对于 JavaScript,不是使用全局变量,而是由主驱动程序管理,并将它传递给每个需要 API 调用的函数。

阅读和解析 Markdown 语法

下一步是阅读并解析 Markdown 文件中的内容。

Python

    def read_parse_md(fname):
        # 读取并解析 Markdown 文件的函数
        # 读取文件内容,找到并替换加粗和斜体的文本,同时记录这些更改的位置
        with open(fname, 'r') as f:
            content = f.read()
        actions = []
        # 使用正则表达式找出所有加粗和斜体的文本
        matches = re.findall(r'(([_*])([^\2]+?)\2)', content)
        for match in matches:
            md, dl, pt = match
            i = content.find(md)
            j = i + len(pt) + 1
            content = content.replace(md, pt)
            # 根据前缀判断是加粗还是斜体
            action = 'bold' if dl == '*' else 'italic'
            actions.append((action, i, j))
        return content, actions

全屏模式 开启/退出

JavaScript

    async function read_parse_md(fname) {
      var contentBuf = await fs.readFile(fname);
      var content = await contentBuf.toString('utf-8');
      let actions = [];
      const matches = content.matchAll(/(([_*])([^\2]+?)\2)/g);
      for (const match of matches) {
        const [ md, dl, pt ] = match.slice(1, 4);
        var i = content.indexOf(md);
        var j = i + pt.length + 1;
        content = content.replace(md, pt);
        var action = (dl === '*') ? '加粗' : '斜体';
        actions.push([ action, i, j ]);
      }
      return [ content, actions ];
    }

点击此处进入全屏模式,再点击此处退出全屏模式

两个示例几乎是一行行相同的,所以我们一起来分析它们吧。read_parse_md() 这个函数确实做到了:它读取和解析 Markdown 文件,将 Markdown 标记转换为通过 Docs API 发出的格式化操作 actions。

正则表达式(“regex”)用于匹配需要用下划线表示斜体的字符串,例如 _sample_,以及需要用星号表示加粗的字符串,例如 *sample*。一次遍历 content 字符串,将每个样式请求转换为 API "样式操作"。

这个正则表达式看起来可能有点复杂,但它的基本工作原理是这样的:寻找一个开头的 _* 并将其符号保存为 \2(第二个匹配模式)。找到一个匹配后,以非贪婪方式 ? 找到最少字符的闭合符号,并保存整个标记文本(md)、纯文本(pt)以及分隔符(dl)。对于 "_sample_",md_sample_dl_ptsample,将 action 设置为 italic。下表展示了所有这些值:

正则 正则匹配 保存到变量 描述 示例
((...\2)(最外层的括号 () \1 "Markdown:" md 完整的匹配字符串 _sample_
([_*]) \2 "Delimiter:" dl Markdown 标记 _
([^\2]+?) \3 "Plain Text:" pt 去掉分隔符的匹配字符串 sample

正则表达式及匹配结果

最简单的方法来“解读”这些匹配组是 \1 表示第一个左括号,\2 表示第二个,以此类推。

要让文档 API 对任何文本应用样式,它必须知道文本的位置信息,也就是说你的请求必须提供位置信息以及操作。这些是原始偏移:一个起始位置 (i) 和一个结束位置 (j)。所有样式请求都将以这种方式处理,将 (action, i, j) 添加到 actions 数组中。

最后,所有标记将被清除,content "还原"为纯文本。actions数组包含了通过API进行样式设置的所有"操作指令"。

创建和编辑 Google 文档

有了所有的内容和指令,我们需要编写代码来创建一个空的新 Google 文档,并将数据字符串写进去。每个任务都需要用到一个函数:

功能 描述
create_doc() 创建新的或空的 Google 文档并返回其文件 ID
write_text() 将文本写入指定文件 ID 的文档中

Python 代码

下面的代码定义了两个函数:`create_doc` 和 `write_text`。`create_doc` 函数用于创建一个文档并将文件名作为标题,返回文档的 ID。`write_text` 函数用于在指定位置插入文本。
def create_doc(fname):
    # 返回创建文档后的文档ID
    return DOCS.documents().create(
            body={'title': fname}).execute().get('documentId')

def write_text(text, docs_id):
    requests = [{'insertText': {'location': {'index': 1}, 'text': text}}]
    DOCS.documents().batchUpdate(body={'requests': requests},
            documentId=docs_id, fields='').execute()

进入全屏 退出全屏

JavaScript(一种编程语言)

    async function create_doc(DOCS, fname) {
      const rsp = await DOCS.documents.create({ requestBody: { title: fname } });
      return rsp.data.documentId;
    }
    // 创建文档函数

    async function write_text(DOCS, text, docs_id) {
      const requests = [ { insertText: { location: { index: 1 }, text: text } } ];
      await DOCS.documents.batchUpdate({
        requestBody: { requests: requests },
        documentId: docs_id
      });
    }
    // 写入文本到文档的函数

切换到全屏 切换回正常模式

创建一个新的 Google 文档只需要提供文档名称;本例中即为移除 .md 文件扩展名的 Markdown 文件名,也就是去掉 .md 的 Markdown 文件名。create_doc() 函数会发出请求,并返回新生成的文档(即 Google Drive 中的文件)的文件 ID。

更新 Google 文档需要一个或多个请求,比如 这个 API 请求。在这个具体例子中,请求类型是 InsertTextRequest,至少需要两个参数。

  1. 要插入的文本 text(请保留英文原样)
  2. 要插入的位置(索引位置或偏移值)

在新的文档里,在索引 1(而不是 0)处插入内容是正确的位置。Node.js 版本的 write_text() 函数唯一的区别在于,API 客户端对象 DOCS 在每次调用时传递,而在 Python 中,则使用同一个全局变量。

在 Google 文档中排版文本

拼图的最后一块是一个格式化 Google 文档中文本的函数;这个函数是用来格式化 Google 文档中文本的:

Python

    def format_text(actions, docs_id):
        'format text with requested Markdown styling'
        requests = [{
            'updateTextStyle': {
                'range': {'startIndex': i, 'endIndex': j},
                'textStyle': {style: True}, 'fields': style,
            }
        } for style, i, j in actions]
        DOCS.documents().batchUpdate(body={'requests': requests},
                documentId=docs_id, fields='').execute()

全屏,退出全屏

JavaScript(一种脚本语言)

    async function format_text(DOCS, actions, docs_id) {
      const requests = [];
      for (const [ style, i, j ] of actions) {
        requests.push({
          updateTextStyle: {
            range: { startIndex: i, endIndex: j },
            textStyle: { [ style ]: true }, fields: style
          }
        });
      }

      await DOCS.documents.batchUpdate({
          requestBody: { requests: requests },
          documentId: docs_id
      });
    }

全屏模式/退出全屏

它使用文档的文件ID(docs_id)和样式操作数组(actions),构建一个等效的updateTextStyle API请求数组,这意味着每个请求包括加粗或斜体命令以及受影响文本的位置。

在处理完 actions 并将其内容输出后,如果 requests 看起来像一个 JSON 对象的数组,你完全正确。

    [{'updateTextStyle': {'斜体': True,
                          '范围': {'结束索引': 17, '起始索引': 4},
                          '文本样式': {'italic': True}}},
     {'updateTextStyle': {'粗体': True,
                          '范围': {'结束索引': 47, '起始索引': 37},
                          '文本样式': {'bold': True}}}]

全屏 退出全屏.

它最后一件事是将数组和文件ID传递给API来执行请求。这是一个非常基础的Markdown指令处理程序。目的是让你开始熟悉Docs API,而不是编写一个完整的Markdown解析器,你可以根据需要尝试编写一个完整的Markdown解析器作为练习。

主要驱动力

虽然这些功能都很不错,但需要一个“主要的”程序来把这些功能整合在一起。它们分别是:

Python

    if __name__ == '__main__':
        text, actions = read_parse_md(FILENAME)
        print('** 解析 Markdown 文件 %r 并获取其样式操作' % FILENAME)
        docs_fn = FILENAME.replace('.md', '')  # 去掉 MD 文件扩展名
        docs_id = create_doc(docs_fn)
        print('** 创建文档 %r (ID: %s)' % (docs_fn, docs_id))
        write_text(text, docs_id)
        print('** 将 %r 插入文档' % text)
        format_text(actions, docs_id)
        print('** 完成文档中的 Markdown 格式化' % actions)

进入全屏 退出全屏

JavaScript(一种编程语言)

    async function md2docs(authClient) {
      const DOCS = google.docs({ version: 'v1', auth: authClient });
      const [ text, 操作] = await read_parse_md(FILENAME);
      console.log(`** 解析了 Markdown 文件 '${FILENAME}' 及样式操作`);
      const docs_fn = await FILENAME.replace('.md', '');
      const docs_id = await create_doc(DOCS, docs_fn);
      console.log(`** 创建了文档 '${docs_fn}' (ID: ${docs_id})`);
      await write_text(DOCS, text, docs_id);
      console.log(`** 将文本插入文档:${text.replace(/\n/g, "\\n")}`);
      await format_text(DOCS, 操作, docs_id);
      console.log(`** 文档中的 Markdown 格式化完成:`, 操作);
    }

    authorize().then(md2docs).catch(console.error);

点击全屏 点击退出全屏

这两个代码段的功能只有细微差别,具体表现在:

  1. 在 JS 中,DOCS API 客户端对象仅限于此代码块,而 Python 中则是全局的。
  2. JS 代码的最后一行调用 authorize() 函数,并将返回的 authClient 对象传递给主要的 md2docs() 函数,该函数可以捕获并记录异常信息。

不管您用哪种语言,这个 app 的做法如下:

  1. 读取并解析 Markdown 内容
  2. 新建一个空白的 Google 文档
  3. 将纯文本内容写入文档
  4. 在文档中完成所有格式化要求
先决条件和所需设置

运行脚本时,输出会严格按照那个配方。不过,在运行任何脚本之前,你需要先完成以下这些必要的步骤:

  1. 创建新项目 从云/开发人员控制台 或使用 gcloud projects create . . . 命令;或者复用现有项目。
  2. 启用 Google Docs API。选择以下三种常见方式之一来启用 API:
  • DevConsole 手动 -- 从 DevConsole 手动启用 API,步骤如下:
  1. 访问 DevConsole

  2. 在页面右侧找到并点击“启用”按钮;在左侧导航栏中点击 选项卡,搜索“Docs”,并启用。
  • DevConsole 链接 -- 如果你是第一次使用 Google API 或者没有手动在 DevConsole 中启用 API 的经验,可以这样做:
  1. 访问 API 列表页面 以了解 API 详情,并在那里启用它。

  2. 或者,直接点击 此链接 ,启用 API。
  • 命令行 (gcloud) -- 喜欢在终端操作的人可以使用 Cloud Shell 或者在本地计算机上,通过已安装的 Cloud SDK 包含的 gcloud 命令行工具。
  1. 如果你是这种情况,使用此命令启用 API:gcloud services enable docs.googleapis.com

  2. 使用此命令确认已启用的 API:gcloud services list
  3. 创建 OAuth 客户端 ID 和密钥 凭证 并下载到本地文件系统作为 client_secret.json。如果没有这个文件,代码示例将 无法运行
  4. 安装 Google API 客户端库
  • NodeJS (16+): 使用以下命令安装所需包:

  • npm i (使用 package.json)

  • 或者手动安装包:npm i googleapis @google-cloud/local-auth

  • Python 2 或 3 (新认证方式): 在你的正常或 virtualenv 环境中运行此命令,这是大多数人使用的标准方式:

  • pip install -r requirements.txt (或 pip3)

  • 或者手动安装包:pip install -U pip google-api-python-client google-auth-httplib2 google-auth-oauthlib

  • Python 2 或 3 (旧认证方式): 如果你仍然使用旧的 Python 认证库并且有旧代码,运行此命令以确保你拥有最新版本的这些库:

  • pip install -r requirements-old.txt (或 pip3)

  • 或者手动安装包:pip install -U pip google-api-python-client oauth2client (或 pip3)

  • 例如,对于 Python 特别地来说,这里的 2.x 指的是 2.7,如果你正计划迁移到 3.x,你 绝对 不应该使用任何旧的版本。对于 3.x,几乎所有的版本应该都可以工作,但建议使用 3.9 或更新版本。

做好了以上所有事情后,你就可以开始了哦。顺便说一下,运行这个应用的成本应该不会有任何额外费用。

⚠️ 请注意:成本: "免费" 到一定限度
尽管许多 Google 产品和 API 是免费的,但并非所有产品和 API 都是免费的。尽管如此,使用 GWS API 不是完全 "免费",但它完全包括在您每月的 "订阅" 中,无论是付费订阅者(定价详情)还是免费的 Google 消费者账户(带有不带有 Gmail,Gmail 是可选的),这意味着您的每月订阅费用为零。

然而,这种 "免费" 使用是有一定限制的……请遵守每个 API 的既定配额限制。不出所料,付费订阅者比免费账户拥有更多的配额。虽然没有广泛公开,您可以在 Google Apps Script 配额页面 上查看详细的限制。

运行这个脚本程序

但每种语言渲染的对象会有一些细微的差别,如下所示,类似于你看到的,因为我们知道这些应用的“运行原理”,运行这些应用会产生我们预期的结果。

Python(一种编程语言)

    $ python md2docs.py
    ** 解析 Markdown 文件 'quickbrownfox.md' 并执行样式操作
    ** 生成 'quickbrownfox' (ID: bfENGvI9vCE2cabBCqv3Hq6qvFoL0nfDPfQZeZLY6ubQ)
    ** 将 'The quick, brown fox jumped over the lazy dogs.\n' 插入到文档中
    ** 完成文档的 Markdown 格式化:[斜体(4, 17), 粗体(37, 47)]

全屏模式 全屏退出

JavaScript

    $ node md2docs.mjs
    ** 解析了 Markdown 文件 'quickbrownfox.md' 并执行了相应的样式操作
    ** 创建了 'quickbrownfox' (ID: ATjQg2PqFQxqmiRNIi1TL9gjXBFWV7cw0i4ytGtddt7K)
    ** 将 'The quick, brown fox jumped over the lazy dogs.\n' 插入到文档中
    ** 完成了文档的 Markdown 格式化:[ ['斜体', 4, 17], ['加粗', 37, 47] ]

进入全屏 退出全屏

如果你能在文本刚添加到 Google 文档的瞬间暂停应用并打开,就会看到类似这样的内容。

插入到 Google 文档中的简单文本

然而,除非你暂停执行,否则很难截到图,因为格式化很快就会开始,也就是说,你看到的将是最终结果。

Google 文档中的格式化字符串

概要和接下来的步骤

现在你知道如何使用正则表达式创建一个简陋的Markdown解析器,更重要的是,你学会了如何使用Google Docs API。

  1. 创建一个新的 Google 文档文件
  2. 在 Google 文档中输入文本
  3. 在 Google 文档中设置文本格式

虽然该示例用来开始一个简单的 Markdown 解析器,但主要目的是让读者熟悉这个 API,这个 API 上线时间不长(于 2017 年推出)。如果你想支持更丰富的 Markdown 语法,可以考虑用 Python 的 markdown2 或者 Node.js 的 Showdown

如果你将这篇帖子中演示的示例脚本与将 Google 文档导出为 PDF 文件帖子中的示例结合起来,你就会拥有一个解决方案,该方案可以自动获取 Markdown 文件,生成格式化的 Google 文档文件,并导出相应的 PDF 以供使用,供您组织或客户使用。

你也可以更进一步:将有价值的企业数据从一组庞大的 CSV 文件中提取出来并导入到 Google 表格中,将它们导入,然后利用 Gemini API 生成内容摘要,撰写一系列 Google 文档,最后生成 PDF 文件给你的老板、管理层,甚至是付费客户。

这些只是些想法。我的目的是通过展示可能来激发你的灵感。在未来的文章中,我还会介绍其他的 GWS API。为了好玩,我还会写一篇“codegen”(代码生成)的文章,让像 ChatGPT 和 Gemini 这样的大语言模型来生成这样的应用,讨论我得到的结果,并进行比较。

总结

如果你在这篇文章中发现了错误或 bug,或者你有想让我讨论的话题,请在下方留言或在仓库中提交 issue。我乐于在旅途中遇到用户……你可以在我的咨询页面旅行日历中查看我是否会访问你的社区。

参考文献

下面是一些可能对你有用的、与本文相关的资源。

代码片段

谷歌文档 API

GWS APIs 和 OAuth2 相关信息

Google API, 客户端库工具

作者的其他相关文章

免责声明: 我曾在多个GWS产品团队工作,时间大约在2013年至2018年之间。尽管产品信息力求准确,但这些观点仅仅是个人看法。


(保留原格式)

郑雅硕(Wesley Chun), MSCS,是Google Cloud (GCP) 和 Google Workspace (GWS) 的Google Developer Expert (GDE),著有普雷蒂斯霍尔畅销书“Core Python”系列,合著有“Python Web Development with Django”,并且曾在Linux Journal及CNET撰文。他经营CyberWeb,专注于GCP及GWS API和无服务器平台,提供Python及App Engine迁移服务,以及Python培训及工程服务。郑雅硕曾是雅虎邮件的原始工程师之一,并在谷歌的产品团队工作了超过13年,代表他们的API发言,制作样本应用、代码实验室和视频,涉及无服务器迁移GWS开发者。他拥有加州大学的计算机科学、数学和音乐学位,是Python软件基金会的成员,也是Fellow,并热衷于旅行,参加世界各地的开发者会议、用户组活动和大学。关注他@wescpy以及他的技术博客。觉得这些内容有用的话,联系CyberWeb以获取专业服务或买他一杯咖啡(或茶)

0人推荐
随时随地看视频
慕课网APP