You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Anki 2.1.x中开发反向完形填空(Reverse Cloze)插件

Building a Reverse Cloze Plugin for Anki 2.1.x

Hey there, let's walk through how to solve this reverse cloze card problem step by step— I've got you covered with resources, logic breakdowns, and actionable code snippets!

  • Official Documentation: Open Anki, go to the top menu > Help > Documentation. There's a full section on plugin development that covers card types, field handling, and template rendering—this is your go-to reference for core Anki behavior.
  • Source Code Insights: You can dig into Anki's core code directly from your installation directory (Windows: C:\Program Files\Anki\, macOS: /Applications/Anki.app/Contents/MacOS/). Look for files like cloze.py, card.py, and template.py—these handle all the cloze and card generation logic you'll need to reference.

Core Problem Breakdown & Implementation Ideas

The main hurdles you're hitting are that Anki's built-in cloze cards are strictly one-way, and regular card templates don't process {{cloze:fieldname}} tags correctly. Here are two solid approaches to fix this:

Approach 1: Parse Custom Format + Generate Two Regular Cards

This is the most straightforward method to start with:

  1. Listen for edit/add events in the Anki editor. When it detects your custom cloze format ({{c1::clozed::card type}}), parse out the base sentence, the cloze content, and the reverse prompt.
  2. Auto-create two separate regular cards:
    • Card 1: Front shows This is [card type]., Back shows This is clozed.
    • Card 2: Front shows This is [clozed]., Back shows This is card type.

Approach 2: Custom Card Type + Template Rendering

If you want to keep the interactive cloze feel (click to reveal answers), you can build a custom card type. But you'll need to implement your own cloze tag rendering logic since regular templates don't support this. This is more complex, so start with Approach 1 first.

Code Snippets to Get You Started

Here's a working core implementation for Approach 1, designed to fit into Anki's 2.1.x plugin framework:

1. Basic Plugin Framework (__init__.py)

from aqt import mw
from aqt.editor import Editor
from aqt.qt import *
import re

# Regex to match your custom reverse cloze format: {{c1::A::B}}
REVERSE_CLOZE_PATTERN = re.compile(r'{{c1::(.*?)::(.*?)}}')

def generate_reverse_cloze_cards(editor: Editor):
    # Grab content from the currently active field
    current_field_content = editor.note.fields[editor.currentField]
    match = REVERSE_CLOZE_PATTERN.search(current_field_content)
    
    if not match:
        QMessageBox.warning(mw, "Oops!", "No reverse cloze format detected. Use {{c1::cloze-content::reverse-prompt}} to proceed.")
        return
    
    # Extract the two interchangeable parts
    cloze_content = match.group(1)
    reverse_prompt = match.group(2)
    
    # Build front/back content for both cards
    card1_front = current_field_content.replace(match.group(0), f"This is [{reverse_prompt}].")
    card1_back = f"This is {cloze_content}."
    
    card2_front = current_field_content.replace(match.group(0), f"This is [{cloze_content}].")
    card2_back = f"This is {reverse_prompt}."
    
    # Create first note/card (matches current deck and field structure)
    note1 = editor.note.__class__()
    note1.fields[0] = card1_front  # Assumes first field is "Front"
    note1.fields[1] = card1_back   # Assumes second field is "Back"
    note1.model()['did'] = editor.note.model()['did']
    mw.col.addNote(note1)
    
    # Create second note/card
    note2 = editor.note.__class__()
    note2.fields[0] = card2_front
    note2.fields[1] = card2_back
    note2.model()['did'] = editor.note.model()['did']
    mw.col.addNote(note2)
    
    # Refresh Anki's interface to show new cards
    mw.reset()
    QMessageBox.information(mw, "Success!", "Two reverse cloze cards generated!")

# Add a custom button to the Anki editor
def add_reverse_cloze_button(editor: Editor):
    btn = QPushButton("Make Reverse Cloze")
    btn.clicked.connect(lambda: generate_reverse_cloze_cards(editor))
    editor.iconsBox.addWidget(btn)

# Hook the button into the editor's setup process
Editor.setupButtons.append(add_reverse_cloze_button)

2. Key Logic Explanations

  • Regex Matching: The regex pulls out the two interchangeable parts from your custom format. Adjust the pattern if you want to support multiple cloze pairs per field.
  • Card Creation: We create new notes using the same model as your current note, so they inherit your deck settings and field structure automatically.
  • UI Integration: The Editor.setupButtons hook lets us add a custom button directly to Anki's edit window for quick, one-click card generation.

Quick Tips

  • Backup First: Always back up your Anki collection before testing plugins to avoid accidental data loss.
  • Flexibility: If you use non-default field names/positions, tweak the field indices (like note1.fields[0]) to match your setup.
  • Advanced Cloze Rendering: For Approach 2, check out Anki's cloze.py source code to see how it processes cloze tags—you can adapt that logic to render your own two-way cloze templates.

内容的提问来源于stack exchange,提问作者Yannick

火山引擎 最新活动