Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@types/escape-html": "^1.0.4",
"@types/glidejs__glide": "^3.6.6",
"@types/js-cookie": "^3.0.6",
"@types/minimist": "^1.2.5",
"@types/node": "^20.17.31",
"@types/remark-heading-id": "^1.0.0",
Expand Down Expand Up @@ -84,6 +85,7 @@
"escape-html": "^1.0.3",
"github-slugger": "^2.0.0",
"html-to-image": "^1.11.13",
"js-cookie": "^3.0.5",
"lucide-svelte": "^0.325.0",
"maplibre-gl": "^5.4.0",
"maplibregl-mapbox-request-transformer": "^0.0.2",
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions project.inlang/default-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export default {
'https://cdn.jsdelivr.net/npm/@inlang/plugin-paraglide-js-adapter@latest/dist/index.js'
],
'plugin.inlang.messageFormat': {
pathPattern: './messages/{locale}.json'
pathPattern: './src/temp/translations/json/{locale}.json'
},
'plugin.paraglide-js-adapter': {
routing: {
strategy: 'prefix',
strategy: 'prefix-all-locales',
defaultLocale: 'en'
}
}
Expand Down
68 changes: 68 additions & 0 deletions scripts/git-touch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/bash

# Check if a file was provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <markdown_file>"
exit 1
fi

FILE="$1"

# Check if the file exists
if [ ! -f "$FILE" ]; then
echo "Error: File '$FILE' not found."
exit 1
fi

# Check if the file has YAML frontmatter (starts with ---)
if ! grep -q "^---" "$FILE"; then
echo "Error: File does not have YAML frontmatter."
exit 1
fi

# Get current timestamp
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Find the first two occurrences of --- in the file to identify the frontmatter section
FIRST_LINE=$(grep -n "^---" "$FILE" | head -1 | cut -d':' -f1)
SECOND_LINE=$(grep -n "^---" "$FILE" | head -2 | tail -1 | cut -d':' -f1)

if [ -z "$FIRST_LINE" ] || [ -z "$SECOND_LINE" ] || [ "$FIRST_LINE" -eq "$SECOND_LINE" ]; then
echo "Error: Could not properly identify YAML frontmatter boundaries."
exit 1
fi

# Create a temporary file for processing
TMP_FILE=$(mktemp)

# Extract the frontmatter, modify it, then reconstruct the file
head -n "$FIRST_LINE" "$FILE" > "$TMP_FILE"
sed -n "$((FIRST_LINE+1)),$((SECOND_LINE-1))p" "$FILE" > "$TMP_FILE.frontmatter"

# Check if git-touch already exists in frontmatter
if grep -q "git-touch:" "$TMP_FILE.frontmatter"; then
# Update the git-touch line
sed -i "s/^git-touch:.*$/git-touch: $TIMESTAMP/" "$TMP_FILE.frontmatter"
else
# Add git-touch as a new line
echo "git-touch: $TIMESTAMP" >> "$TMP_FILE.frontmatter"
fi

# Append modified frontmatter to the temp file
cat "$TMP_FILE.frontmatter" >> "$TMP_FILE"
echo "---" >> "$TMP_FILE"

# Append the rest of the original file after the frontmatter
tail -n +$((SECOND_LINE+1)) "$FILE" >> "$TMP_FILE"

# Replace original with modified file
mv "$TMP_FILE" "$FILE"
rm -f "$TMP_FILE.frontmatter"

# Stage the file
git add "$FILE"

# Commit with message
git commit -m "git-touch $(basename "$FILE")"

echo "Successfully touched and committed $(basename "$FILE")"
18 changes: 18 additions & 0 deletions scripts/git-untouch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

# Script to remove the git-touch field from markdown frontmatter in posts and translations
# Usage: ./git-untouch.sh

set -e

echo "Removing git-touch from markdown files..."

# Process main posts directory
echo "Processing src/posts/*.md"
find src/posts -name "*.md" | xargs sed -i '/^git-touch:/d'

# Process translation directories
echo "Processing src/temp/translations/md/*/*.md"
find src/temp/translations/md -path "src/temp/translations/md/*/*.md" | xargs sed -i '/^git-touch:/d'

echo "Complete! Git-touch fields have been removed."
39 changes: 21 additions & 18 deletions scripts/inlang-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,11 @@ import {
writeSettingsFile
} from '../src/lib/l10n'
import { setupTranslationRepo } from './translation/git-ops'
import { createSymlinkIfNeeded, ensureDirectoriesExist } from './translation/utils'
import { cullCommentary, createSymlinkIfNeeded, ensureDirectoriesExist } from './translation/utils'

// Load environment variables from .env file
dotenv.config()

// Configuration - same as in vite.config.ts
const PROJECT_PATH = './project.inlang'
const OUTPUT_PATH = './src/lib/paraglide'
const COMPILE_ARGS = {
project: PROJECT_PATH,
outdir: OUTPUT_PATH,
strategy: ['cookie', 'url', 'preferredLanguage', 'baseLocale'] as (
| 'cookie'
| 'url'
| 'preferredLanguage'
| 'baseLocale'
| 'globalVariable'
| 'localStorage'
)[]
}
function setupEnglishSupport(verbose: boolean): void {
// English markdown files are loaded directly from source in routes/[slug]/+page.ts
if (verbose) console.log(' \u2713 English markdown files will be loaded directly from source')
Expand Down Expand Up @@ -93,6 +78,11 @@ function regenerateSettings(verbose = false): void {
`\n\ud83d\udd04 Setting up translation repository (need at least ${settings.locales}...`
)
setupTranslationRepo(L10NS_BASE_DIR, verbose)
if (verbose) console.log(`\n🧹 Cleaning up translation files to remove LLM commentary...`)
for (const locale of settings.locales) {
if (locale === 'en') continue
cullCommentary(path.join(MESSAGE_L10NS, `${locale}.json`), verbose)
}
}

// For English locale, we only need to provide messages file for Paraglide
Expand All @@ -118,8 +108,21 @@ function regenerateSettings(verbose = false): void {

console.log(`\ud83d\udd04 Compiling Paraglide runtime from settings...`)
try {
// Run the Paraglide compiler with the necessary Node.js flags
compile(COMPILE_ARGS)
compile({
project: './project.inlang',
outdir: './src/lib/paraglide',
strategy: ['url', 'cookie', 'preferredLanguage', 'baseLocale'],
// Create concrete URL patterns structure with current locale set
urlPatterns: [
{
pattern: ':protocol://:domain(.*)::port?/:path(.*)?',
localized: settings.locales.map((locale) => [
locale,
`:protocol://:domain(.*)::port?/${locale}/:path(.*)?`
])
}
]
})
console.log(`\u2705 Paraglide runtime compiled successfully!`)
} catch (error) {
console.error('\u274c Failed to compile Paraglide runtime:', (error as Error).message)
Expand Down
33 changes: 32 additions & 1 deletion scripts/translation/git-ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,24 @@ export async function initializeGitCache(options: {
console.log(
`\ud83d\udd04 Setting up translation repository from ${options.repo} into ${options.dir}`
)
console.log(`Using ${options.token ? 'authenticated' : 'unauthenticated'} Git access`)

// Time the clone operation
console.time('⏱️ Git Clone')
await options.git.clone(remote, options.dir)
console.timeEnd('⏱️ Git Clone')

await options.git.cwd(options.dir)

// Test if we're authenticated by checking remote URL format
try {
const remoteUrl = await options.git.remote(['get-url', 'origin'])
const isAuthenticated = remoteUrl.includes('@')
console.log(`Authentication status: ${isAuthenticated ? 'SUCCESS' : 'FAILURE'}`)
} catch (err) {
console.log(`Failed to verify authentication: ${err.message}`)
}

// Always set git config in case we need to make local commits
await options.git.addConfig('user.name', options.username)
await options.git.addConfig('user.email', options.email)
Expand All @@ -125,11 +140,24 @@ export async function initializeGitCache(options: {
* @param git - The SimpleGit instance used to retrieve the log.
* @returns A Promise that resolves to a Map where keys are file paths and values are the latest commit dates.
*/
export async function getLatestCommitDates(git: SimpleGit): Promise<Map<string, Date>> {
export async function getLatestCommitDates(
git: SimpleGit,
repoType: string = 'repo'
): Promise<Map<string, Date>> {
console.log(`Starting git log retrieval for ${repoType} commit dates...`)
const latestCommitDatesMap = new Map<string, Date>()

const timerLabelLog = `⏱️ Git Log Retrieval - ${repoType}`
console.time(timerLabelLog)
const log = await git.log({
'--stat': 4096
})
console.timeEnd(timerLabelLog)

console.log(`Retrieved ${log.all.length} commits for ${repoType} date analysis`)

const timerLabelParse = `⏱️ Parse Git Log - ${repoType}`
console.time(timerLabelParse)
for (const entry of log.all) {
const files = entry.diff?.files
if (!files) continue
Expand All @@ -139,6 +167,9 @@ export async function getLatestCommitDates(git: SimpleGit): Promise<Map<string,
}
}
}
console.timeEnd(timerLabelParse)

console.log(`Parsed dates for ${latestCommitDatesMap.size} files in ${repoType}`)
return latestCommitDatesMap
}

Expand Down
13 changes: 9 additions & 4 deletions scripts/translation/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ export const generateMarkdownPrompt: PromptGenerator = (
) => {
return `${commonHead(languageName, 'Markdown', promptAdditions)}

Maintain the structure of the document and don't modify script elements, HTML tags, link targets (including section links starting with a number sign) and file names. The content of social media widgets has to remain unchanged as well. I repeat: DO NOT CHANGE LINK TARGETS. DO NOT REMOVE SCRIPT TAGS OR COMPONENTS. The document starts with Frontmatter metadata enclosed in three dashes. Don't translate the keys of the metadata, only the values. Always make sure the result is valid Markdown syntax:
Maintain the structure of the document. Don't modify script elements, HTML tags, link targets (including section links starting with a number sign) and file names. The content of social media widgets has to remain unchanged as well. I repeat: DO NOT CHANGE LINK TARGETS. DO NOT REMOVE SCRIPT TAGS OR COMPONENTS. The document starts with Frontmatter metadata enclosed in three dashes. Don't translate the keys of the metadata, only the values. Always make sure the result is valid Markdown syntax:

${content}

Do not start with \`\`\`md or new lines, just return the Markdown.

Translated Markdown:`
}

export function generateReviewPrompt(languageName: string) {
return `Please review and improve your translation to ${languageName} to ensure it meets the highest standards of quality.
return `Please review and (only if necessary) improve your translation to ${languageName} to ensure it meets the highest standards of quality.

Focus on:
1. Accuracy of meaning compared to typical English expressions
Expand All @@ -45,12 +46,16 @@ Focus on:
5. Maintaining the original formatting and technical elements

Make necessary improvements while preserving:
- All technical elements (HTML tags, links, script elements)
- All technical elements (keys, HTML tags, links, script elements)
- Document structure and formatting
- Special instructions in comments
- File names and technical terms when appropriate

Return the improved version in the same format, without any additional markup or explanations.`
Return the possibly improved text in the same format.

All of your response will be used to generate website pages. Readers don't want to see your own translation notes. Do NOT tell us that you have done the work, or why particular decisions were made. That would make your response invalid. Only return the translation itself.

Translation:`
}

function commonHead(languageName: string, format: string, promptAdditions: string) {
Expand Down
Loading