gitlink-cli/workflows/academic/11-research-citation.ps1

118 lines
4.9 KiB
PowerShell

# GitLink Research - Scenario 6: Citation Format Generator (PowerShell)
param(
[string]$Owner, [string]$Repo, [string]$Format = "all",
[string]$Output = "", [switch]$DryRun
)
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
Import-Module "$ScriptDir\..\lib\common.psm1" -Force -WarningAction SilentlyContinue
Import-Module "$ScriptDir\..\lib\research-common.psm1" -Force -WarningAction SilentlyContinue
$ErrorActionPreference = "Stop"
Check-Auth
$resolved = Resolve-OwnerRepo -Owner $Owner -Repo $Repo
$Owner = $resolved.Owner; $Repo = $resolved.Repo
$Today = Get-DateToday
Log-Title "GitLink Research - Citation Generator"
# 1. Fetch repo metadata
Log-Step "Fetching repo metadata..."
$repoJson = Invoke-GLCheck @("repo", "+info", "--owner", $Owner, "--repo", $Repo)
$repoName = if ($repoJson.data.name) { $repoJson.data.name } elseif ($repoJson.data.full_name) { $repoJson.data.full_name } else { "$Owner/$Repo" }
$repoDesc = if ($repoJson.data.description) { $repoJson.data.description } else { "" }
$updatedAt = if ($repoJson.data.updated_at) { $repoJson.data.updated_at } else { "" }
# DOI detection
$doi = ""
if ($repoDesc -match '10\.\d{4,}/[\w.\-/]+') { $doi = $Matches[0] }
if ($doi) { Log-Info " DOI detected: $doi" }
# 2. Get latest release
Log-Step "Fetching latest version..."
$releaseJson = Invoke-GL @("release", "+list", "--owner", $Owner, "--repo", $Repo, "--limit", "1")
$version = if ($releaseJson.ok -and $releaseJson.data[0].tag_name) { $releaseJson.data[0].tag_name } else { "v0.0.0-dev" }
$releaseDate = if ($releaseJson.ok -and $releaseJson.data[0].created_at) { $releaseJson.data[0].created_at } else { $updatedAt }
if ($releaseDate.Length -ge 10) { $releaseDate = $releaseDate.Substring(0, 10) }
$releaseYear = if ($releaseDate.Length -ge 4) { $releaseDate.Substring(0, 4) } else { (Get-Date).Year }
# 3. Get members
Log-Step "Fetching contributors..."
$membersJson = Invoke-GL @("repo", "+members", "--owner", $Owner, "--repo", $Repo, "--limit", "20")
$authorNames = @()
if ($membersJson.ok) {
$data = if ($membersJson.data.members) { $membersJson.data.members } else { $membersJson.data }
if ($data -is [array]) {
$authorNames = $data | ForEach-Object { if ($_.name) { $_.name } elseif ($_.login) { $_.login } else { "" } } | Where-Object { $_ }
}
}
if ($authorNames.Count -eq 0) { $authorNames = @($Owner) }
# 4. Get repo URL
$repoUrl = try { git remote get-url origin 2>$null } catch { "" }
if (-not $repoUrl) { $repoUrl = "https://gitlink.org.cn/$Owner/$Repo" }
$repoUrl = $repoUrl -replace '\.git$', ''
# Authors formatting
$bibtexAuthors = Format-AuthorsBibtex $authorNames
$apaAuthors = Format-AuthorsAPA $authorNames
# MLA
$parts0 = $authorNames[0] -split '\s+'
$mlaAuthors = "$($parts0[-1]), $($parts0[0])"
if ($authorNames.Count -gt 1) { $mlaAuthors += ", et al." }
# GB/T 7714
$gbAuthors = ($authorNames | Select-Object -First 3) -join ", "
if ($authorNames.Count -gt 3) { $gbAuthors += "et al." }
# Short name for BibTeX key
$shortName = $Repo -replace '[^a-zA-Z0-9_-]', '_'
# Generate output
$citationBody = ""
if ($Format -eq "bibtex" -or $Format -eq "all") {
$citationBody += "@software{$shortName,`n author = {$bibtexAuthors},`n title = {$repoName},`n version = {$version},`n date = {$releaseDate},`n publisher = {GitLink},`n url = {$repoUrl}"
if ($doi) { $citationBody += ",`n doi = {$doi}" }
$citationBody += ",`n note = {$repoDesc}`n}`n`n"
}
if ($Format -eq "apa" -or $Format -eq "all") {
$citationBody += "$apaAuthors ($releaseYear). $repoName (Version $version) [Computer software].`n GitLink. $repoUrl`n`n"
}
if ($Format -eq "mla" -or $Format -eq "all") {
$citationBody += "$mlaAuthors. $repoName. Version $version, GitLink,`n $releaseDate, $repoUrl.`n`n"
}
if ($Format -eq "gbt7714" -or $Format -eq "all") {
$citationBody += "[1] $gbAuthors. $repoName[CP/OL]. $version. GitLink,`n $releaseDate[$Today]. $repoUrl.`n`n"
}
if ($Format -eq "cff" -or $Format -eq "all") {
$cffDate = if ($releaseDate.Length -ge 10) { $releaseDate.Substring(0, 10) } else { $releaseDate }
$citationBody += "cff-version: 1.2.0`nmessage: `"If you use this software, please cite it as below.`"`nauthors:`n"
foreach ($a in $authorNames) {
if (-not $a) { continue }
$parts = $a -split '\s+'
$citationBody += " - family-names: $($parts[-1])`n given-names: $($parts[0])`n"
}
$citationBody += "title: `"$repoName`"`nversion: $version`ndate-released: $cffDate`nurl: `"$repoUrl`"`nrepository-code: `"$repoUrl.git`"`n"
if ($doi) { $citationBody += "doi: $doi`n" }
}
Divider
Write-Host $citationBody
Divider
if ($Output) {
if (-not $DryRun) { $citationBody | Out-File -FilePath $Output -Encoding UTF8; Log-Ok "Written to: $Output" }
}
Log-Info "Repo: $Owner/$Repo"
Log-Info "Version: $version | Released: $releaseDate | Contributors: $($authorNames.Count)"
if ($doi) { Log-Info "DOI: $doi" }
Log-Info "Format: $Format"
Log-Ok "Citation generation complete"