openchemlib 9.9.0 → 9.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,6 +67,11 @@ interface ToMolfileOptions {
67
67
  * @default undefined
68
68
  */
69
69
  customLabelPosition?: 'normal' | 'superscript' | 'auto' | undefined;
70
+ /**
71
+ * Remove custom atom labels
72
+ * @default false
73
+ */
74
+ removeCustomAtomLabels?: boolean;
70
75
  }
71
76
 
72
77
  export interface AtomQueryFeatures {
@@ -1280,6 +1285,17 @@ export declare class Molecule {
1280
1285
  */
1281
1286
  getName(): string;
1282
1287
 
1288
+ /**
1289
+ * This method will return the next custom label that can be used for an atom
1290
+ * If the provided label is already used, it will try to increment it
1291
+ * If no label is provided, it will start from '1'
1292
+ * The incrementing works for numbers and letters (lower and uppercase)
1293
+ * If the label contains both letters and numbers, only the number part is incremented
1294
+ * If the label ends with Z or z, it will return '1' as next label
1295
+ * @param label - optional label to start from
1296
+ */
1297
+ getNextCustomAtomLabel(label?: string): string;
1298
+
1283
1299
  /**
1284
1300
  * The stereo problem flag is set by the stereo recognition (available
1285
1301
  * equal/above helper level cHelperParities) if an atom has over- or
@@ -1288,6 +1288,40 @@ function init(OCL) {
1288
1288
  delete OCL.GenericUIHelper;
1289
1289
  }
1290
1290
 
1291
+ // lib/extend/appendGetNextCustomAtomLabel.js
1292
+ function appendGetNextCustomAtomLabel(Molecule2) {
1293
+ Molecule2.prototype.getNextCustomAtomLabel = function getNextCustomAtomLabel(label) {
1294
+ let nextLabel = label || "1";
1295
+ const existingLabels = /* @__PURE__ */ new Set();
1296
+ for (let i = 0; i < this.getAllAtoms(); i++) {
1297
+ const existingLabel = this.getAtomCustomLabel(i);
1298
+ if (existingLabel) {
1299
+ existingLabels.add(existingLabel);
1300
+ }
1301
+ }
1302
+ let counter = 0;
1303
+ while (existingLabels.has(nextLabel) && counter++ < 100) {
1304
+ nextLabel = getNextLabel(nextLabel);
1305
+ }
1306
+ return nextLabel;
1307
+ };
1308
+ }
1309
+ function getNextLabel(label) {
1310
+ const match = label.match(/(\d+)/);
1311
+ if (match) {
1312
+ const number = Number.parseInt(match[1], 10);
1313
+ return label.replace(/(\d+)/, (number + 1).toString());
1314
+ }
1315
+ const match2 = label.match(/([a-yA-Y])([^a-zA-Z]*)$/);
1316
+ if (match2) {
1317
+ const char = match2[1];
1318
+ const nextChar = String.fromCodePoint(char.codePointAt(0) + 1);
1319
+ if (nextChar === "Z" || nextChar === "z") return "1";
1320
+ return label.replace(/([a-yA-Y])([^a-zA-Z]*)$/, `${nextChar}$2`);
1321
+ }
1322
+ return "1";
1323
+ }
1324
+
1291
1325
  // lib/extend/utils/changeMolfileCustomLabelPosition.js
1292
1326
  function changeMolfileCustomLabelPosition(molecule, customLabelPosition) {
1293
1327
  switch (customLabelPosition) {
@@ -1369,6 +1403,14 @@ function extendFromMolfile(Molecule2) {
1369
1403
  }
1370
1404
 
1371
1405
  // lib/extend/extendToMolfile.js
1406
+ var CUSTOM_ATOMS_LABELS_TAGS = [
1407
+ "M STY",
1408
+ "M SLB",
1409
+ "M SAL",
1410
+ "M SDT",
1411
+ "M SDD",
1412
+ "M SED"
1413
+ ];
1372
1414
  function extendToMolfile(Molecule2) {
1373
1415
  const _toMolfile = Molecule2.prototype.toMolfile;
1374
1416
  Molecule2.prototype.toMolfile = function toMolfile(options = {}) {
@@ -1376,14 +1418,20 @@ function extendToMolfile(Molecule2) {
1376
1418
  const {
1377
1419
  includeCustomAtomLabelsAsALines = false,
1378
1420
  includeCustomAtomLabelsAsVLines = false,
1379
- customLabelPosition
1421
+ customLabelPosition,
1422
+ removeCustomAtomLabels = false
1380
1423
  } = options;
1381
1424
  changeMolfileCustomLabelPosition(molecule, customLabelPosition);
1382
1425
  const molfile = _toMolfile.call(this);
1383
- if (!includeCustomAtomLabelsAsALines && !includeCustomAtomLabelsAsVLines) {
1426
+ if (!includeCustomAtomLabelsAsALines && !includeCustomAtomLabelsAsVLines && !removeCustomAtomLabels) {
1384
1427
  return molfile;
1385
1428
  }
1386
- const lines = molfile.split("\n");
1429
+ let lines = molfile.split("\n");
1430
+ if (removeCustomAtomLabels) {
1431
+ lines = lines.filter(
1432
+ (line) => !CUSTOM_ATOMS_LABELS_TAGS.some((tag) => line.startsWith(tag))
1433
+ );
1434
+ }
1387
1435
  if (lines.length < 4 || !lines[3].includes("V2000")) {
1388
1436
  return molfile;
1389
1437
  }
@@ -1436,6 +1484,7 @@ function extendOCL(OCL) {
1436
1484
  };
1437
1485
  extendFromMolfile(Molecule2);
1438
1486
  extendToMolfile(Molecule2);
1487
+ appendGetNextCustomAtomLabel(Molecule2);
1439
1488
  function parseMoleculeFromText(text) {
1440
1489
  if (!text) {
1441
1490
  return null;
@@ -71143,7 +71192,7 @@ function getExports($wnd) {
71143
71192
  $sendStats("moduleStartup", "end");
71144
71193
  $gwt && $gwt.permProps && __gwtModuleFunction.__moduleStartupDone($gwt.permProps);
71145
71194
  const toReturn = $wnd["OCL"];
71146
- toReturn.version = "9.9.0";
71195
+ toReturn.version = "9.11.0";
71147
71196
  return toReturn;
71148
71197
  }
71149
71198
  var isBrowserWindow = typeof window !== "undefined" && typeof window.document !== "undefined";
@@ -71287,8 +71336,8 @@ export {
71287
71336
  };
71288
71337
  /**
71289
71338
  * openchemlib - Manipulate molecules
71290
- * @version v9.9.0
71291
- * @date 2025-10-07T16:21:21.464Z
71339
+ * @version v9.11.0
71340
+ * @date 2025-10-13T06:58:26.504Z
71292
71341
  * @link https://github.com/cheminfo/openchemlib-js
71293
71342
  * @license BSD-3-Clause
71294
71343
  */