DeployPages

-- slugify: 파일명 안전하게 변환
function slugify(name)
  local s = string.lower(name)
  s = string.gsub(s, "%s+", "-")        -- 공백 → -
  s = string.gsub(s, "[^%w%-/]", "")    -- 특수문자 제거 (/, - 제외)
  return s
end

-- [Alias](page.md) 처리
function convertAliasLinks(text)
  text = string.gsub(text, "%[%[([^%]|]+)|([^%]]+)%]%]", function(target, alias)
    local link = slugify(target)
    return "[" .. alias .. "](" .. link .. ".md)"
  end)
  return text
end

-- [Page](Page.md) 처리
function convertWikiLinks(text)
  -- [Page](Page.md) → [Page](Page.md)
  text = string.gsub(text, "%[%[([^%]]+)%]%]", function(link)
    return "[" .. link .. "](" .. link .. ".md)"
  end)

  return text
end

-- URL을 찾아 마크다운 링크 [URL](URL)로 변환하는 함수
function linkify(text)
  -- 이미 마크다운 링크 안에 있거나, 이미지 링크인 경우를 제외하고
  -- http/https로 시작하는 URL만 찾아 치환합니다.
  -- 패턴: (공백 또는 줄바꿈)(http...)
  local urlPattern = "([^%[%(!])(https?://[%w-_%.%?%/%+=&#%%]+)"

  -- URL을 [URL](URL) 형태로 변경
  local linkedText = text:gsub(urlPattern, "%1[%2](%2)")

  return linkedText
end

--  제거 (원하면 주석 처리)
function cleanup(text)
  text = string.gsub(text, "#%w+", "")

  -- 불필요한 공백 정리
  text = string.gsub(text, "\n%s*\n%s*\n+", "\n\n")

  return text
end

function runDeploy()
    -- 0 clean up old dist files
    local oldDistFiles = query[
        from p = index.tag "page"
        where p.name:startsWith("dist/")
        select p.name
    ](
        from p = index.tag "page"
        where p.name:startsWith("dist/")
        select p.name
    .md)

    for _, oldFile in ipairs(oldDistFiles) do
        space.deletePage(oldFile)
    end

    -- 1. 배포 대상 선정 (Library 제외, private 제외)
    local publicPages = query[
        from p = index.tag "page"
        where not table.includes(p.tags, "private")
          and not p.name:startsWith("Library/")
          and not p.name:startsWith("dist/")    
          and not p.name:startsWith("CONFIG")
          and not p.name:startsWith("SETTINGS")
          and not p.name:startsWith("_")    
        select p.name
    ](
        from p = index.tag "page"
        where not table.includes(p.tags, "private")
          and not p.name:startsWith("Library/")
          and not p.name:startsWith("dist/")    
          and not p.name:startsWith("CONFIG")
          and not p.name:startsWith("SETTINGS")
          and not p.name:startsWith("_")    
        select p.name
    .md)

    print("--- 배포 프로세스 시작 ---")
    local count = 0

    for _, name in ipairs(publicPages) do
        -- 2. 본문 읽기
        local content = space.readPage(name)
        local newContent = convertAliasLinks(content)
        newContent = linkify(newContent)
        newContent = convertWikiLinks(newContent)
        newContent = cleanup(newContent)

        if newContent then
            -- 3. 배포용 경로 설정 (예: 'dist/파일명')
            -- 실버불렛 내부에 'dist'라는 가상 폴더를 만들어 결과물을 모읍니다.
            local deployPath = "dist/" .. name

            -- 4. 파일 쓰기 (기존 내용 덮어쓰기)
            space.writePage(deployPath, newContent)

            print("복사 완료: " .. name .. " -> " .. deployPath)
            count = count + 1
        end
    end

    editor.flashNotification(count .. "개의 파일이 dist/ 폴더로 복사되었습니다.", "info")

    -- 5. SilverBullet의 Git: Sync 또는 Git: Push 명령어 실행
    -- command.invoke를 사용하여 실버불렛 내장 명령어를 호출합니다.
    editor.invokeCommand("Git: Snapshot") -- git add & commit 역할
    editor.invokeCommand("Git: Sync")     -- git pull & push 역할

    editor.flashNotification("빌드 및 Git Push 완료!")  
end

command.define {
    name = "Custom: Deploy to Dist",
    run = runDeploy
}