How the Auxiliary Code (辅码) System Works in Wanxiang: A Technical Deep Dive

Wanxiang's auxiliary code system enables precise Chinese character input by appending user-defined supplemental codes after pinyin, parsing these from dictionary comments via the super_lookup.lua processor to filter candidates.

The auxiliary code (辅码) system in Wanxiang provides a sophisticated mechanism for disambiguating Chinese character input by combining standard pinyin with secondary lookup codes. Implemented in the amzxyz/rime_wanxiang repository, this feature leverages Lua scripting to parse semicolon-delimited codes from dictionary comments, enabling both exact and fuzzy matching strategies that prioritize user-defined shortcuts over standard reverse lookup.

Where Auxiliary Codes Are Stored

Wanxiang stores auxiliary codes in two primary locations, allowing flexibility between built-in tables and custom dictionary annotations.

Built-in Auxiliary Tables

The built-in aux table resides in custom/aux_code.txt, which the build script aux_go.py references at line 168 (AUX_FILE = "custom/aux_code.txt") to inject into the runtime dictionary. This file maps individual characters to their permissible auxiliary codes using a strict tab-delimited format:

呵	;kk;kk;kk;dz;ks;kk;kh
嗄	;kw;kw;kx;dh;kd;kw;kh
錒	;jk;jk;ja;zz;qb;;jv

Each line contains the character, a tab separator, and a semicolon-delimited list of auxiliary strings. The leading semicolon ensures empty entries are handled correctly during parsing.

Comment-Driven Auxiliary Data

Any dictionary entry may embed auxiliary codes directly in its comment field using the same ;code1;code2;… syntax. This approach powers the Pro version, which pulls aux data from reverse-lookup dictionaries without modifying the core table. During candidate generation, the engine extracts these codes from the comment text to build the auxiliary lookup index.

Enabling the Aux Source in Your Schema

The schema configuration determines whether the engine processes auxiliary data. In wanxiang_pro.schema.yaml, the data_source field controls this behavior:


# wanxiang_pro.schema.yaml

data_source: ['aux', 'db']   # load aux codes from comments first, then DB reverse lookup

When 'aux' appears in the data_source array, the Lua engine sets env.has_comment = true during initialization (lines 28-31 of super_lookup.lua). This flag triggers the parsing pipeline for all subsequent candidates. In the Standard schema, only ['db'] is listed by default, meaning auxiliary codes remain inactive unless the user explicitly adds 'aux' to the configuration.

Parsing Comments into Auxiliary Lists

The core parsing logic lives in parse_comment_codes() at lines 66-96 of wanxiang/lua/super_lookup.lua. This function transforms raw comment text into structured auxiliary data:

local function parse_comment_codes(comment, pattern, target_len, enable_tone)
    local parts = split_string(comment, pattern)
    local result = {}
    
    for i, part in ipairs(parts) do
        local p1, p2 = part:find(";")
        local pinyin_part = p1 and part:sub(1, p1-1) or part
        local codes_part  = p1 and part:sub(p2+1) or ""

        local codes_list = {}
        if #codes_part > 0 then                     -- Extract aux codes
            for c in codes_part:gmatch("[^,]+") do
                local trimmed = c:gsub("^%s+", ""):gsub("%s+$", "")
                if #trimmed > 0 then table.insert(codes_list, trimmed) end
            end
        end
        if enable_tone then                         -- Extract tone numbers (optional)
            local tone = get_tone_from_pinyin(pinyin_part)
            if tone then table.insert(codes_list, tone) end
        end
        result[i] = codes_list
    end
    return result
end

The function returns a nested table where each index corresponds to a character position, containing an array of valid auxiliary strings and optional tone digits. The delimiter for splitting comment segments defaults to a space-apostrophe combination (" '"), configurable via speller/delimiter in the schema.

Building Raw Candidate Data

During the lookup loop, each candidate receives a raw_data record that caches parsed auxiliary information. Lines 53-64 of super_lookup.lua demonstrate this assignment:

-- A. Aux data (from comment)
if env.has_comment then
    local comment_text = genuine and genuine.comment or ""
    if comment_text ~= "" then
        comment_cache[cache_key] = parse_comment_codes(...)
        raw_data.aux = comment_cache[cache_key]           -- Stored for matching
        raw_data._comment_internal = comment_cache[cache_key]  -- Used for tone borrowing
    end
end

The comment cache prevents redundant parsing of identical comment strings across multiple candidates, significantly improving performance during large dictionary lookups.

Splitting and Processing User Input

When input arrives, the engine separates the primary pinyin from the auxiliary code using split_lookup_input():

local _, fuma, s_start, s_end = split_lookup_input(ctx_input, env.search_key_str, env.bypass_prefix)

The variable fuma contains everything after the delimiter (e.g., kk in 呵/kk). The engine then filters this into:

  • clean_fuma: The actual auxiliary code characters
  • tone_filter_seq: Extracted tone digits (7-0) when enable_tone is active

This separation occurs in the main processing loop at lines 12-22 of super_lookup.lua.

Matching Auxiliary Codes Against Input

For each configured data_source (processed in array order), the engine retrieves the appropriate code list and performs matching:

  1. Exact group matching for single-character candidates using group_match()
  2. Fuzzy recursive matching for multi-character words using match_fuzzy_recursive()

The logic at lines 31-46 implements this discrimination:

if source_type == 'aux' then
    if cand_len == 1 then
        if group_match(codes_seq[1], clean_fuma) then is_match = true end
    else
        if match_fuzzy_recursive(codes_seq, 1, clean_fuma, 1, memo, false) then is_match = true end
    end
elseif source_type == 'db' then
    -- Similar algorithm with DB-specific flag
end

Priority ordering is enforced by the data_source array sequence. Since ['aux', 'db'] places 'aux' first, matches from the auxiliary code system outrank standard reverse-lookup matches, ensuring user-defined shortcuts take precedence.

Tone Borrowing for Reverse Lookup

When enable_tone = true, the system extracts tone numbers from comments and stores them in borrowed_tones. During the tone-filter step (lines 20-22), the engine accepts tone digits as valid auxiliary inputs if they appear in the borrowed set:

if not has_tone and source_type == 'db' then
    if borrowed_tones[k] and borrowed_tones[k][tone_input] then has_tone = true end
end

This allows inputs like shi/5 (tone 5) to retrieve the character if the comment contains that tone marking, effectively treating tonal information as auxiliary codes during DB lookups.

Practical Usage Examples

Desired Character Input Pattern Mechanism
he/kk or he/dz The aux part kk matches against the list from custom/aux_code.txt
ai/vw Matches comment-embedded code vw from the reverse dictionary
(tone) shi/5 enable_tone treats 5 as aux code via tone borrowing
Multi-char word zhong/kw match_fuzzy_recursive walks each character's aux list to fit kw

The delimiter (default /) is configurable via the speller/delimiter option in your schema YAML.

Summary

  • Auxiliary codes are semicolon-delimited strings stored in custom/aux_code.txt or dictionary comments
  • Enable the feature by adding 'aux' to the data_source array in your schema configuration
  • Parsing occurs via parse_comment_codes() at lines 66-96 of super_lookup.lua, handling both aux strings and tone numbers
  • Matching uses exact matching for single characters and fuzzy recursive matching for phrases, with 'aux' sources outranking 'db' sources
  • Tone borrowing allows tone digits to function as auxiliary codes when enable_tone is enabled

Frequently Asked Questions

What is an auxiliary code in Wanxiang?

An auxiliary code is a user-defined supplemental key sequence that follows the main pinyin input (after a delimiter) to disambiguate character selection. According to the amzxyz/rime_wanxiang source code, these codes are semicolon-delimited strings stored in dictionary comments or the custom/aux_code.txt file, parsed by the super_lookup.lua processor to filter candidates during lookup.

How do I enable auxiliary codes in my schema?

Add 'aux' to the data_source array in your schema YAML file (e.g., wanxiang_pro.schema.yaml). The standard schema lists only ['db'] by default, which disables auxiliary processing. When 'aux' is present, the engine sets env.has_comment = true (lines 28-31 of super_lookup.lua) and begins parsing comment fields for auxiliary data.

Can I use tone numbers as auxiliary codes?

Yes, when enable_tone is set to true in your configuration, the system extracts tone numbers from dictionary comments and treats them as valid auxiliary inputs. This allows typing pinyin followed by a tone digit (e.g., shi/5) to filter characters by their tonal classification, implemented in the tone-filter logic at lines 20-22 of super_lookup.lua.

What is the difference between 'aux' and 'db' data sources?

The 'aux' source refers to auxiliary codes parsed from dictionary comments or aux_code.txt, while 'db' refers to standard reverse-lookup codes from the dictionary database. When both appear in data_source, 'aux' matches take precedence over 'db' matches because the engine processes sources in array order and buckets results accordingly, ensuring user-defined shortcuts override default reverse lookups.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →