Skip to content

Commit

Permalink
Add support for markers
Browse files Browse the repository at this point in the history
  • Loading branch information
ku1ik committed May 15, 2023
1 parent f01c257 commit 7f90b31
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 1 deletion.
42 changes: 41 additions & 1 deletion lib/asciinema/asciicasts/asciicast.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ defmodule Asciinema.Asciicasts.Asciicast do
field :archived_at, :utc_datetime_usec
field :terminal_line_height, :float
field :terminal_font_family, :string
field :markers, :string

timestamps()

Expand Down Expand Up @@ -100,7 +101,8 @@ defmodule Asciinema.Asciicasts.Asciicast do
:theme_name,
:idle_time_limit,
:terminal_line_height,
:terminal_font_family
:terminal_font_family,
:markers
])
|> validate_number(:cols_override, greater_than: 0, less_than: 1024)
|> validate_number(:rows_override, greater_than: 0, less_than: 512)
Expand All @@ -111,6 +113,44 @@ defmodule Asciinema.Asciicasts.Asciicast do
)
|> validate_inclusion(:terminal_font_family, custom_terminal_font_families)
|> validate_number(:snapshot_at, greater_than: 0)
|> validate_change(:markers, &validate_markers/2)
end

defp validate_markers(_, markers) do
case parse_markers(markers) do
{:ok, _} -> []
{:error, index} -> [markers: "invalid syntax in line #{index + 1}"]
end
end

def parse_markers(markers) do
results =
markers
|> String.trim()
|> String.split("\n")
|> Enum.map(&parse_marker/1)

case Enum.find_index(results, fn result -> result == :error end) do
nil -> {:ok, results}
index -> {:error, index}
end
end

defp parse_marker(marker) do
parts =
marker
|> String.trim()
|> String.split(~r/\s+-\s+/, parts: 2)
|> Kernel.++([""])
|> Enum.take(2)

with [t, l] <- parts,
{t, ""} <- Float.parse(t),
true <- String.length(l) < 100 do
{t, l}
else
_ -> :error
end
end

def snapshot_changeset(struct, snapshot) do
Expand Down
9 changes: 9 additions & 0 deletions lib/asciinema_web/templates/asciicast/edit.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@
</div>
</div>

<div class="form-group row">
<%= label f, :markers, class: "col-sm-4 col-md-3 col-lg-3 col-form-label" %>
<div class="col-sm-8 col-md-9 col-lg-9">
<%= textarea f, :markers, class: "form-control", rows: 6, placeholder: "Example:\n\n5.0 - Intro\n11.3 - Installation\n32.0 - Configuration\n66.5 - Tips & Tricks" %>
<%= error_tag f, :markers %>
<small class="form-text text-muted">Each line is a marker defined as <code>[time] - [label]</code>.</small>
</div>
</div>

<div class="form-group row">
<div class="offset-sm-4 col-sm-8 offset-md-3 col-md-9 offset-lg-3 col-lg-9">
<br>
Expand Down
11 changes: 11 additions & 0 deletions lib/asciinema_web/views/asciicast_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule AsciinemaWeb.AsciicastView do
use AsciinemaWeb, :view
import Scrivener.HTML
alias Asciinema.Asciicasts
alias Asciinema.Asciicasts.Asciicast
alias AsciinemaWeb.Endpoint
alias AsciinemaWeb.Router.Helpers.Extra, as: RoutesX
alias AsciinemaWeb.UserView
Expand Down Expand Up @@ -42,6 +43,7 @@ defmodule AsciinemaWeb.AsciicastView do
terminalLineHeight: asciicast.terminal_line_height,
customTerminalFontFamily: asciicast.terminal_font_family,
poster: poster(asciicast.snapshot),
markers: markers(asciicast.markers),
idleTimeLimit: asciicast.idle_time_limit,
title: title(asciicast),
author: author_username(asciicast),
Expand Down Expand Up @@ -135,6 +137,15 @@ defmodule AsciinemaWeb.AsciicastView do
"data:text/plain," <> text <> @csi_init <> "?25l"
end

defp markers(nil), do: nil

defp markers(markers) do
case Asciicast.parse_markers(markers) do
{:ok, markers} -> Enum.map(markers, &Tuple.to_list/1)
{:error, _} -> nil
end
end

defp line_to_text(segments) do
segments
|> Enum.map(&segment_to_text/1)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Asciinema.Repo.Migrations.AddMarkersToAsciicasts do
use Ecto.Migration

def change do
alter table(:asciicasts) do
add :markers, :text
end
end
end
14 changes: 14 additions & 0 deletions test/asciinema/asciicasts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,18 @@ defmodule Asciinema.AsciicastsTest do
assert stream_v0 == stream_v2
end
end

describe "parse_markers/1" do
test "returns markers for valid syntax" do
result = Asciicast.parse_markers("1.0 - Intro\n2.5\n5.0 - Tips & Tricks\n")

assert result == {:ok, [{1.0, "Intro"}, {2.5, ""}, {5.0, "Tips & Tricks"}]}
end

test "returns error for invalid syntax" do
result = Asciicast.parse_markers("1.0 - Intro\nFoobar\n")

assert result == {:error, 1}
end
end
end

0 comments on commit 7f90b31

Please sign in to comment.