Module:Lorebook/Debug: Difference between revisions

上传带详细调试输出的 Lorebook 模块
 
Escape curly braces ({/}) in debug output to prevent template invocation
 
(8 intermediate revisions by the same user not shown)
Line 22: Line 22:


local function containsAny(haystack, needles)
local function containsAny(haystack, needles)
   local s = ' ' .. haystack:lower() .. ' '
   local s = haystack:lower()
   for _, n in ipairs(needles) do
   for _, n in ipairs(needles) do
     if n ~= '' then
     if n ~= '' then
       local escaped = n:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]', '%%%1')
      local needle = n:lower()
      -- Escape special pattern characters
       local escaped = needle:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]', '%%%1')
     
      -- Try multiple matching strategies
      -- 1. Exact match
      if s == needle then
        return true
      end
     
      -- 2. Word boundary patterns
       local patterns = {
       local patterns = {
         '%f[%w]' .. escaped .. '%f[%W]',
         '^' .. escaped .. '%W',   -- At start followed by non-word
         '[%W]' .. escaped .. '[%W]',
         '%W' .. escaped .. '%W',   -- Surrounded by non-word chars
        '^' .. escaped .. '[%W]',
         '%W' .. escaped .. '$',   -- Preceded by non-word at end
         '[%W]' .. escaped .. '$',
         '^' .. escaped .. '$'     -- Exact match (redundant but safe)
         '^' .. escaped .. '$'
       }
       }
     
       for _, pattern in ipairs(patterns) do
       for _, pattern in ipairs(patterns) do
         if s:find(pattern) then
         if s:find(pattern) then
           return true
           return true
         end
         end
      end
     
      -- 3. Simple substring match as last resort
      if s:find(escaped, 1, true) then
        return true
       end
       end
     end
     end
Line 69: Line 84:


local function getAllConcepts(world)
local function getAllConcepts(world)
   local query = string.format('[[Category:Concept]][[Belongs to world::%s]]', world)
   local query = {
  local res = mw.smw.ask(query, {
    '[[Category:Concept]][[Belongs to world::' .. world .. ']]',
    mainlabel = '-',
     '?Plist=plist',
     ['?Plist'] = 'plist',
     '?AliChat=alichat',
     ['?AliChat'] = 'alichat',
     '?Primary keys=primary',
     ['?Primary keys'] = 'primary',
     '?Secondary keys=secondary',
     ['?Secondary keys'] = 'secondary',
     '?Logic=logic',
     ['?Logic'] = 'logic',
     '?Key mode=mode',
     ['?Key mode'] = 'mode',
     '?Parent concept=parent',
     ['?Parent concept'] = 'parent',
     '?Non-recursable=nonrec',
     ['?Non-recursable'] = 'nonrec',
     '?Placement=placement',
     ['?Placement'] = 'placement',
     limit = 999
     limit = 999
   })
   }
 
  local res = mw.smw.ask(query)
    
    
   if not res then return {} end
   if not res then return {} end
Line 88: Line 104:
   local normalized = {}
   local normalized = {}
   for i, row in ipairs(res) do
   for i, row in ipairs(res) do
    -- Debug: log raw row structure for first result
    if DEBUG and i == 1 then
      local debug_info = "Raw row[1]: " .. tostring(row[1]) .. " (type: " .. type(row[1]) .. ")\n"
      debug_info = debug_info .. "Raw row.primary: " .. tostring(row.primary) .. " (type: " .. type(row.primary) .. ")\n"
      debug_info = debug_info .. "Raw row['Primary keys']: " .. tostring(row['Primary keys']) .. " (type: " .. type(row['Primary keys']) .. ")\n"
     
      -- List all keys in the row table
      debug_info = debug_info .. "\nAll keys in row:\n"
      for k, v in pairs(row) do
        debug_info = debug_info .. "  [" .. tostring(k) .. "] = " .. tostring(v) .. " (type: " .. type(v) .. ")\n"
      end
     
      -- Store debug info in a global to access later
      _G._debug_row_info = debug_info
    end
   
     normalized[i] = {
     normalized[i] = {
       page = normalizeValue(row[1]),
       page = normalizeValue(row[1]), -- First element is the page title
       plist = normalizeValue(row.plist),
       plist = normalizeValue(row.plist),
       alichat = normalizeValue(row.alichat),
       alichat = normalizeValue(row.alichat),
Line 172: Line 204:
   end
   end
   if #chatChunks > 0 then
   if #chatChunks > 0 then
    if #plistChunks > 0 then
      text = text .. '\n'  -- Add extra newline between plist and chat sections
    end
     text = text .. table.concat(chatChunks, '\n')
     text = text .. table.concat(chatChunks, '\n')
   end
   end
Line 187: Line 222:
   local rows = getAllConcepts(world)
   local rows = getAllConcepts(world)
   output = output .. debug_log("Found " .. #rows .. " concepts")
   output = output .. debug_log("Found " .. #rows .. " concepts")
 
  -- Show raw row debug info
  if _G._debug_row_info then
    output = output .. "\n'''Raw SMW data (first row):'''\n<pre>\n" .. _G._debug_row_info .. "</pre>\n"
    _G._debug_row_info = nil  -- Clear after use
  end
    
    
   if #rows == 0 then
   if #rows == 0 then
Line 203: Line 244:
     output = output .. "\n'''Found concepts:'''\n"
     output = output .. "\n'''Found concepts:'''\n"
     for i, r in ipairs(rows) do
     for i, r in ipairs(rows) do
      local primary_debug = "none"
      if r.primary then
        primary_debug = tostring(r.primary) .. " (type: " .. type(r.primary) .. ")"
      end
       output = output .. "* " .. (r.page or "unnamed") ..  
       output = output .. "* " .. (r.page or "unnamed") ..  
                         " (mode: " .. (r.mode or "conditional") ..  
                         " (mode: " .. (r.mode or "conditional") ..  
                         ", primary: " .. (r.primary or "none") .. ")\n"
                         ", primary: " .. primary_debug .. ")\n"
     end
     end
     output = output .. "\n"
     output = output .. "\n"
Line 246: Line 291:
   end
   end
    
    
   output = output .. result
   -- Escape curly braces and use <pre> tag to preserve formatting
    
  if result and result ~= '' then
  if DEBUG then
    result = result:gsub('{', '&#123;'):gsub('}', '&#125;')
     output = output .. "\n</pre>\n"
    output = output .. result .. '\n</pre>\n'
   else
     output = output .. "(empty output)\n</pre>\n"
   end
   end