---
title: "Clean Em Dashes action for ActionClip"
canonical_url: "https://actionclip.app/actions/clean-em-dashes"
document_type: "standalone_action"
official: true
action_count: 1
catalog_schema_version: 1
catalog_revision: "2026-09-24.2"
catalog_published_at: "2026-09-24T13:54:17Z"
---

# Clean Em Dashes action for ActionClip

Replace excessive em dashes with natural punctuation.

## What it does

Converts paired and standalone em dashes to commas, changes dash-led lines to Markdown bullets, and cleans spaced en dashes and double hyphens. Numeric en-dash ranges stay unchanged.

## Action details

| Field | Value |
| --- | --- |
| Category | Text Editing & Formatting |
| Action type | JavaScript |
| Default result | Replace selected text by default |
| Internet | Not required |

## Action and outcome

| Action | Outcome |
| --- | --- |
| **Clean Em Dashes** — Selected text: The new release — announced yesterday — delivers faster speeds. | The new release, announced yesterday, delivers faster speeds. |

## How to replace excessive em dashes with natural punctuation with ActionClip

1. Select the text you want to use.
2. Choose **Clean Em Dashes** from ActionClip.
3. In editable text, ActionClip replaces the selection immediately. In read-only text, it opens the result for review and copying.

## Requirements

No setup required.

## Privacy

Runs locally in ActionClip’s JavaScript sandbox. Selected text does not leave your Mac.

## Action script

````javascript
function isHorizontalSpace(character) {
  return character === " " || character === "\t";
}

function dashLengthAt(text, index) {
  var character = text.charAt(index);
  if (character === "—") return 1;

  if (character === "-" && text.charAt(index + 1) === "-") {
    var end = index + 2;
    while (text.charAt(end) === "-") end += 1;
    return end - index;
  }

  if (
    character === "–" &&
    isHorizontalSpace(text.charAt(index - 1)) &&
    isHorizontalSpace(text.charAt(index + 1))
  ) {
    return 1;
  }

  return 0;
}

function removeTrailingSpace(text) {
  var end = text.length;
  while (end > 0 && isHorizontalSpace(text.charAt(end - 1))) end -= 1;
  return text.slice(0, end);
}

function cleanProseLine(line) {
  var output = "";
  var index = 0;

  while (index < line.length) {
    var dashLength = dashLengthAt(line, index);
    if (dashLength === 0) {
      output += line.charAt(index);
      index += 1;
      continue;
    }

    output = removeTrailingSpace(output);
    var nextIndex = index + dashLength;
    while (nextIndex < line.length && isHorizontalSpace(line.charAt(nextIndex))) {
      nextIndex += 1;
    }

    var left = output.charAt(output.length - 1);
    var right = line.charAt(nextIndex);
    var rightHasPunctuation = /[.,;:!?)\]}]/.test(right);
    var leftHasPunctuation = /[.,;:!?(\[{]/.test(left);

    if (left && right && !rightHasPunctuation) {
      if (!leftHasPunctuation) output += ",";
      if (left !== "(" && left !== "[" && left !== "{") output += " ";
    }

    index = nextIndex;
  }

  return output;
}

function cleanLine(line) {
  var bullet = line.match(/^([ \t]*)(?:—|-{2,})[ \t]+/);
  if (bullet) {
    return bullet[1] + "- " + cleanProseLine(line.slice(bullet[0].length));
  }
  return cleanProseLine(line);
}

function run(selected_text) {
  if (!selected_text) return "";

  var pieces = selected_text.split(/(\r\n|[\n\r\u000B\u000C\u0085\u2028\u2029])/);
  for (var index = 0; index < pieces.length; index += 2) {
    pieces[index] = cleanLine(pieces[index]);
  }
  return pieces.join("");
}
````

## Links

- [HTML listing](https://actionclip.app/actions/clean-em-dashes)
- [Download action definition](https://actionclip.app/actions/clean-em-dashes.actionclip)
- [Browse Text Editing & Formatting actions](https://actionclip.app/marketplace#marketplace-textTools)
- [All Marketplace listings](https://actionclip.app/marketplace)
