-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
Hello everyone,
I created https://github.com/elixir-makeup/makeup_syntect a while ago to add syntax highlighting for many languages to ExDoc. I am wondering if it may also be worth to be included on preview.hex.pm. The only concern I have is that I don't know if it is suitable for a production environment, as it's primarily meant to run at compile time when generating docs and I haven't used it in a project at runtime yet. It is based on syntect, a Rust library that uses Sublime syntax files and mapping its tokens to makeup tokens.
I did some local tests using Benchee and it seems to run quite well performance wise:
defmodule MyBench do
def run do
Benchee.run(
%{
"elixir" => fn -> Makeup.highlight(elixir_code(), language: "elixir") end,
"javascript" => fn -> Makeup.highlight(javascript_code(), language: "javascript") end
},
time: 10,
memory_time: 2
)
end
defp elixir_code do
~S"""
defmodule Phoenix.LiveView.AsyncResult do
@moduledoc ~S'''
Provides a data structure for tracking the state of an async assign.
See the `Async Operations` section of the `Phoenix.LiveView` docs for more information.
## Fields
* `:ok?` - When true, indicates the `:result` has been set successfully at least once.
* `:loading` - The current loading state
* `:failed` - The current failed state
* `:result` - The successful result of the async task
'''
defstruct ok?: false,
loading: nil,
failed: nil,
result: nil
alias Phoenix.LiveView.AsyncResult
@doc \"\"\"
Creates an async result in loading state.
## Examples
iex> result = AsyncResult.loading()
iex> result.loading
true
iex> result.ok?
false
\"\"\"
def loading do
%AsyncResult{loading: true}
end
@doc \"\"\"
Updates the loading state.
When loading, the failed state will be reset to `nil`.
## Examples
iex> result = AsyncResult.loading(%{my: :loading_state})
iex> result.loading
%{my: :loading_state}
iex> result = AsyncResult.loading(result)
iex> result.loading
true
\"\"\"
def loading(%AsyncResult{} = result) do
%{result | loading: true, failed: nil}
end
def loading(loading_state) do
%AsyncResult{loading: loading_state, failed: nil}
end
end
"""
end
defp javascript_code do
"""
const ARIA = {
anyOf(instance, classes) {
return classes.find((name) => instance instanceof name);
},
isFocusable(el, interactiveOnly) {
return (
(el instanceof HTMLAnchorElement && el.rel !== "ignore") ||
(el instanceof HTMLAreaElement && el.href !== undefined) ||
(!el.disabled &&
this.anyOf(el, [
HTMLInputElement,
HTMLSelectElement,
HTMLTextAreaElement,
HTMLButtonElement,
])) ||
el instanceof HTMLIFrameElement ||
(el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true") ||
(!interactiveOnly &&
el.getAttribute("tabindex") !== null &&
el.getAttribute("aria-hidden") !== "true")
);
},
attemptFocus(el, interactiveOnly) {
if (this.isFocusable(el, interactiveOnly)) {
try {
el.focus();
} catch {
// that's fine
}
}
return !!document.activeElement && document.activeElement.isSameNode(el);
},
focusFirstInteractive(el) {
let child = el.firstElementChild;
while (child) {
if (this.attemptFocus(child, true) || this.focusFirstInteractive(child)) {
return true;
}
child = child.nextElementSibling;
}
},
focusFirst(el) {
let child = el.firstElementChild;
while (child) {
if (this.attemptFocus(child) || this.focusFirst(child)) {
return true;
}
child = child.nextElementSibling;
}
},
focusLast(el) {
let child = el.lastElementChild;
while (child) {
if (this.attemptFocus(child) || this.focusLast(child)) {
return true;
}
child = child.previousElementSibling;
}
},
};
export default ARIA;
"""
end
endOperating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 32 GB
Elixir 1.18.4
Erlang 28.0.1
JIT enabled: true
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 28 s
Benchmarking elixir ...
Benchmarking javascript ...
Calculating statistics...
Formatting results...
Name ips average deviation median 99th %
javascript 906.67 1.10 ms ±20.52% 1.06 ms 1.64 ms
elixir 479.97 2.08 ms ±9.80% 2.04 ms 2.63 ms
Comparison:
javascript 906.67
elixir 479.97 - 1.89x slower +0.98 ms
Memory usage statistics:
Name average deviation median 99th %
javascript 4.05 MB ±0.02% 4.05 MB 4.05 MB
elixir 10.05 MB ±0.00% 10.05 MB 10.05 MB
Comparison:
javascript 4.05 MB
elixir 10.05 MB - 2.48x memory usage +6.00 MB
If you're interested, I am happy to send a pull request!
Metadata
Metadata
Assignees
Labels
No labels