or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Pofile

1

2

Pofile is a JavaScript library for parsing and serializing GNU Gettext PO (Portable Object) files, widely used for internationalization (i18n) and localization (l10n) of software applications. It provides comprehensive support for all standard Gettext features including message contexts, plural forms, translator comments, extracted comments, reference strings, and message flags.

3

4

## Package Information

5

6

- **Package Name**: pofile

7

- **Package Type**: npm

8

- **Language**: JavaScript (with TypeScript definitions)

9

- **Installation**: `npm install pofile`

10

11

## Core Imports

12

13

```javascript

14

var PO = require('pofile');

15

```

16

17

For ES modules (modern environments):

18

19

```javascript

20

import PO from 'pofile';

21

```

22

23

The package exports a single PO class constructor function.

24

25

## Basic Usage

26

27

```javascript

28

var PO = require('pofile');

29

30

// Create new empty PO file

31

var po = new PO();

32

33

// Parse PO file from string

34

var po = PO.parse(myString);

35

36

// Load PO file from disk (Node.js only)

37

PO.load('text.po', function (err, po) {

38

if (err) throw err;

39

// Use po object

40

});

41

42

// Create a translation item

43

var item = new PO.Item();

44

item.msgid = 'Hello';

45

item.msgstr = ['Hola'];

46

po.items.push(item);

47

48

// Save to disk (Node.js only)

49

po.save('out.po', function (err) {

50

if (err) throw err;

51

});

52

53

// Serialize to string

54

var poString = po.toString();

55

```

56

57

## Capabilities

58

59

### PO File Management

60

61

Create, load, parse, and save PO files with full support for headers and comments.

62

63

```javascript { .api }

64

/**

65

* PO constructor - creates new empty PO file instance

66

*/

67

function PO();

68

69

/**

70

* Load PO file from filesystem (Node.js only)

71

* @param filename - Path to PO file

72

* @param callback - Callback with (err, po) parameters

73

*/

74

PO.load = function(filename, callback);

75

76

/**

77

* Parse PO file content from string

78

* @param data - PO file content as string

79

* @returns PO instance

80

*/

81

PO.parse = function(data);

82

83

/**

84

* Parse Plural-Forms header value

85

* @param pluralFormsString - Plural-Forms header value

86

* @returns Object with nplurals and plural properties

87

*/

88

PO.parsePluralForms = function(pluralFormsString);

89

```

90

91

### PO File Serialization

92

93

Convert PO objects back to standard PO file format.

94

95

```javascript { .api }

96

/**

97

* Write PO file to disk (Node.js only)

98

* @param filename - Output file path

99

* @param callback - Callback with (err) parameter

100

*/

101

po.save = function(filename, callback);

102

103

/**

104

* Serialize PO object to string format

105

* @returns String representation of PO file

106

*/

107

po.toString = function();

108

```

109

110

### Translation Item Management

111

112

Create and manage individual translation entries with full Gettext feature support.

113

114

```javascript { .api }

115

/**

116

* PO.Item constructor - creates new translation item/entry

117

* @param options - Object with nplurals property

118

*/

119

function PO.Item(options);

120

121

/**

122

* Serialize item to PO file entry format

123

* @returns String representation of PO item

124

*/

125

item.toString = function();

126

```

127

128

## Data Structures

129

130

### PO Class Properties

131

132

```javascript { .api }

133

/**

134

* PO file instance properties

135

*/

136

interface PO {

137

/** Array of translator comments found at file header */

138

comments: string[];

139

140

/** Array of extracted comments from source code */

141

extractedComments: string[];

142

143

/** PO file headers with standard Gettext header fields */

144

headers: {

145

'Project-Id-Version': string;

146

'Report-Msgid-Bugs-To': string;

147

'POT-Creation-Date': string;

148

'PO-Revision-Date': string;

149

'Last-Translator': string;

150

'Language': string;

151

'Language-Team': string;

152

'Content-Type': string;

153

'Content-Transfer-Encoding': string;

154

'Plural-Forms': string;

155

[name: string]: string;

156

};

157

158

/** Order of headers as they appear in file (used to preserve header sequence when serializing) */

159

headerOrder: string[];

160

161

/** Collection of translation items/entries */

162

items: PO.Item[];

163

}

164

```

165

166

### PO.Item Class Properties

167

168

```javascript { .api }

169

/**

170

* Translation item/entry properties

171

*/

172

interface PO.Item {

173

/** Original message identifier */

174

msgid: string;

175

176

/** Message context for disambiguation */

177

msgctxt: string | null;

178

179

/** Plural form message identifier */

180

msgid_plural: string | null;

181

182

/** Translated message strings (plural forms) */

183

msgstr: string[];

184

185

/** Source code references where message appears */

186

references: string[];

187

188

/** Translator comments */

189

comments: string[];

190

191

/** Comments extracted from source code */

192

extractedComments: string[];

193

194

/** Message flags (e.g., fuzzy, c-format) */

195

flags: { [flag: string]: boolean };

196

197

/** Whether entry is marked obsolete (entries marked with #~ prefix) */

198

obsolete: boolean;

199

200

/** Number of plural forms (defaults to 2) */

201

nplurals: number;

202

}

203

```

204

205

### Parsed Plural Forms

206

207

```javascript { .api }

208

/**

209

* Result of parsing Plural-Forms header

210

*/

211

interface ParsedPluralForms {

212

/** Number of plural forms (undefined if not specified) */

213

nplurals: string | undefined;

214

215

/** Plural form expression (undefined if not specified) */

216

plural: string | undefined;

217

}

218

```

219

220

## Usage Examples

221

222

### Creating Translation Items

223

224

```javascript

225

var PO = require('pofile');

226

var po = new PO();

227

228

// Simple translation

229

var item1 = new PO.Item();

230

item1.msgid = 'Hello World';

231

item1.msgstr = ['Hola Mundo'];

232

po.items.push(item1);

233

234

// Translation with context

235

var item2 = new PO.Item();

236

item2.msgctxt = 'greeting';

237

item2.msgid = 'Hello';

238

item2.msgstr = ['Hola'];

239

po.items.push(item2);

240

241

// Plural translation

242

var item3 = new PO.Item();

243

item3.msgid = 'There is %d item';

244

item3.msgid_plural = 'There are %d items';

245

item3.msgstr = ['Hay %d elemento', 'Hay %d elementos'];

246

po.items.push(item3);

247

248

// Translation with comments and references

249

var item4 = new PO.Item();

250

item4.msgid = 'File';

251

item4.msgstr = ['Archivo'];

252

item4.comments = ['Menu item for File menu'];

253

item4.extractedComments = ['Translators: Keep this short'];

254

item4.references = ['src/menus.js:42'];

255

item4.flags = { fuzzy: true };

256

po.items.push(item4);

257

```

258

259

### Working with Headers

260

261

```javascript

262

var PO = require('pofile');

263

var po = new PO();

264

265

// Set standard headers

266

po.headers['Project-Id-Version'] = 'My App 1.0';

267

po.headers['Language'] = 'es';

268

po.headers['Content-Type'] = 'text/plain; charset=UTF-8';

269

po.headers['Plural-Forms'] = 'nplurals=2; plural=(n != 1);';

270

271

// Control header order

272

po.headerOrder = ['Project-Id-Version', 'Language', 'Content-Type', 'Plural-Forms'];

273

```

274

275

### Parsing and Processing Files

276

277

```javascript

278

var PO = require('pofile');

279

var fs = require('fs');

280

281

// Parse from string

282

var content = fs.readFileSync('messages.po', 'utf8');

283

var po = PO.parse(content);

284

285

// Process items

286

po.items.forEach(function(item) {

287

if (item.flags.fuzzy) {

288

console.log('Fuzzy translation:', item.msgid);

289

}

290

291

if (item.msgid_plural) {

292

console.log('Plural forms:', item.msgstr.length);

293

}

294

295

if (item.msgctxt) {

296

console.log('Context:', item.msgctxt, 'for', item.msgid);

297

}

298

});

299

300

// Filter untranslated items

301

var untranslated = po.items.filter(function(item) {

302

return item.msgstr.every(function(str) { return str === ''; });

303

});

304

305

console.log('Untranslated items:', untranslated.length);

306

307

// Filter obsolete items (marked with #~ prefix)

308

var obsolete = po.items.filter(function(item) {

309

return item.obsolete;

310

});

311

312

console.log('Obsolete items:', obsolete.length);

313

```

314

315

### Handling Plural Forms

316

317

```javascript

318

var PO = require('pofile');

319

320

// Parse plural forms header

321

var pluralInfo = PO.parsePluralForms('nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;');

322

console.log('Number of plural forms:', pluralInfo.nplurals);

323

console.log('Plural expression:', pluralInfo.plural);

324

325

// Create item with proper plural count

326

var item = new PO.Item({ nplurals: parseInt(pluralInfo.nplurals) });

327

item.msgid = 'You have %d message';

328

item.msgid_plural = 'You have %d messages';

329

item.msgstr = ['Tienes %d mensaje', 'Tienes %d mensajes', 'Tienes %d mensajes'];

330

```

331

332

## Platform Support

333

334

- **Node.js**: Full support including file I/O operations (`PO.load`, `po.save`)

335

- **Browser**: Supported via Browserify (excludes file I/O methods)

336

- **Bower**: Available as browser package

337

338

File I/O methods (`PO.load` and `po.save`) are only available in Node.js environments and will not work in browsers.

339

340

## Error Handling

341

342

The library follows Node.js error handling conventions:

343

344

```javascript

345

// Loading files

346

PO.load('messages.po', function(err, po) {

347

if (err) {

348

console.error('Failed to load PO file:', err.message);

349

return;

350

}

351

// Process po object

352

});

353

354

// Saving files

355

po.save('output.po', function(err) {

356

if (err) {

357

console.error('Failed to save PO file:', err.message);

358

return;

359

}

360

console.log('PO file saved successfully');

361

});

362

```

363

364

Parsing operations (`PO.parse`) are synchronous and will throw exceptions on invalid input.