Skip to content

Commit 935df02

Browse files
committed
Search CSS & React types too
1 parent 6281e6a commit 935df02

6 files changed

Lines changed: 396 additions & 67 deletions

File tree

lib/components_guide/research/sources/typescript.ex

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ defmodule ComponentsGuide.Research.Sources.Typescript do
4848
defstruct name: nil, doc: nil, line_start: nil, line_end: nil
4949
end
5050

51+
defmodule Type do
52+
defstruct name: nil, doc: nil, line_start: nil, line_end: nil
53+
end
54+
5155
defmodule Namespace do
5256
defstruct name: nil, doc: nil, line_start: nil, line_end: nil
5357
end
@@ -114,11 +118,86 @@ defmodule ComponentsGuide.Research.Sources.Typescript do
114118

115119
def do_reduce({"interface " <> name_and_extends, n}, %State{mode: nil} = state) do
116120
name = extract_name(name_and_extends)
121+
{doc, line_start} = read_prev_doc(state, n)
122+
123+
case name_and_extends |> String.trim_trailing() |> String.ends_with?("}") do
124+
true ->
125+
output_item = %Interface{
126+
name: name,
127+
doc: doc,
128+
line_start: line_start,
129+
line_end: n
130+
}
117131

132+
%State{mode: nil, output: [output_item | state.output], prev_doc: nil}
133+
134+
false ->
135+
mode = %ModeDefinition{type: :interface, name: name, doc: doc, line_start: line_start}
136+
%State{state | mode: mode, prev_doc: nil}
137+
end
138+
end
139+
140+
def do_reduce({"export interface " <> name_and_extends, n}, %State{mode: nil} = state) do
141+
name = extract_name(name_and_extends)
118142
{doc, line_start} = read_prev_doc(state, n)
119143

120-
mode = %ModeDefinition{type: :interface, name: name, doc: doc, line_start: line_start}
121-
%State{state | mode: mode, prev_doc: nil}
144+
case name_and_extends |> String.trim_trailing() |> String.ends_with?("}") do
145+
true ->
146+
output_item = %Interface{
147+
name: name,
148+
doc: doc,
149+
line_start: line_start,
150+
line_end: n
151+
}
152+
153+
%State{mode: nil, output: [output_item | state.output], prev_doc: nil}
154+
155+
false ->
156+
mode = %ModeDefinition{type: :interface, name: name, doc: doc, line_start: line_start}
157+
%State{state | mode: mode, prev_doc: nil}
158+
end
159+
end
160+
161+
def do_reduce({"export type " <> name_and_extends, n}, %State{mode: nil} = state) do
162+
name = extract_name(name_and_extends)
163+
{doc, line_start} = read_prev_doc(state, n)
164+
165+
case name_and_extends |> String.trim_trailing() |> String.ends_with?(";") do
166+
true ->
167+
output_item = %Type{
168+
name: name,
169+
doc: doc,
170+
line_start: line_start,
171+
line_end: n
172+
}
173+
174+
%State{mode: nil, output: [output_item | state.output], prev_doc: nil}
175+
176+
false ->
177+
mode = %ModeDefinition{type: :type, name: name, doc: doc, line_start: line_start}
178+
%State{state | mode: mode, prev_doc: nil}
179+
end
180+
end
181+
182+
def do_reduce({"type " <> name_and_extends, n}, %State{mode: nil} = state) do
183+
name = extract_name(name_and_extends)
184+
{doc, line_start} = read_prev_doc(state, n)
185+
186+
case name_and_extends |> String.trim_trailing() |> String.ends_with?(";") do
187+
true ->
188+
output_item = %Type{
189+
name: name,
190+
doc: doc,
191+
line_start: line_start,
192+
line_end: n
193+
}
194+
195+
%State{mode: nil, output: [output_item | state.output], prev_doc: nil}
196+
197+
false ->
198+
mode = %ModeDefinition{type: :type, name: name, doc: doc, line_start: line_start}
199+
%State{state | mode: mode, prev_doc: nil}
200+
end
122201
end
123202

124203
def do_reduce({"declare namespace " <> name_and_extends, n}, %State{mode: nil} = state) do
@@ -204,6 +283,14 @@ defmodule ComponentsGuide.Research.Sources.Typescript do
204283
line_end: n
205284
}
206285

286+
:type ->
287+
%Type{
288+
name: mode.name,
289+
doc: mode.doc,
290+
line_start: mode.line_start,
291+
line_end: n
292+
}
293+
207294
:namespace ->
208295
%Namespace{
209296
name: mode.name,
@@ -224,10 +311,75 @@ defmodule ComponentsGuide.Research.Sources.Typescript do
224311
%State{mode: nil, output: [output_item | state.output]}
225312
end
226313

314+
def do_reduce({line, n}, %State{mode: %ModeDefinition{}} = state) do
315+
line = line |> String.trim_trailing()
316+
# terminals = ["}", "};", ";"]
317+
# done? = Enum.any?(terminals, &String.ends_with?(line, &1))
318+
319+
# terminals = ["}", "};", ";"]
320+
end_curly? = String.ends_with?(line, "}") || String.ends_with?(line, "};")
321+
end_semicolon? = String.ends_with?(line, ";")
322+
323+
done? =
324+
case {state.mode.type, end_curly?, end_semicolon?} do
325+
{:namespace, _, _} -> false
326+
{:type, _, end_semicolon?} -> end_semicolon?
327+
{_, end_curly?, _} -> end_curly?
328+
end
329+
330+
case {state.mode.type, done?} do
331+
{_, false} ->
332+
state
333+
334+
{:namespace, _} ->
335+
state
336+
337+
{_, true} ->
338+
mode = state.mode
339+
340+
output_item =
341+
case mode.type do
342+
:interface ->
343+
%Interface{
344+
name: mode.name,
345+
doc: mode.doc,
346+
line_start: mode.line_start,
347+
line_end: n
348+
}
349+
350+
:type ->
351+
%Type{
352+
name: mode.name,
353+
doc: mode.doc,
354+
line_start: mode.line_start,
355+
line_end: n
356+
}
357+
358+
:namespace ->
359+
%Namespace{
360+
name: mode.name,
361+
doc: mode.doc,
362+
line_start: mode.line_start,
363+
line_end: n
364+
}
365+
366+
:global_var ->
367+
%GlobalVariable{
368+
name: mode.name,
369+
doc: mode.doc,
370+
line_start: mode.line_start,
371+
line_end: n
372+
}
373+
end
374+
375+
%State{mode: nil, output: [output_item | state.output]}
376+
end
377+
end
378+
227379
def do_reduce(_, state), do: state
228380

229381
defp extract_name(name_and_extends) do
230-
case String.split(name_and_extends, [" ", ":", "("], parts: 2) do
382+
case String.split(name_and_extends, [" ", ":", "(", "<"], parts: 2) do
231383
[name | _] -> name
232384
_ -> nil
233385
end

lib/components_guide_web/controllers/research_controller.ex

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,59 @@ defmodule ComponentsGuideWeb.ResearchController do
88
alias ComponentsGuideWeb.ResearchView.Section, as: Section
99
alias ComponentsGuide.Research.Sources.Typescript
1010

11-
def show(conn, %{"section" => "dom-types"}) do
11+
defp process_typescript_source(source) do
1212
as_ms = &System.convert_time_unit(&1, :native, :millisecond)
1313

14-
url = "https://cdn.jsdelivr.net/npm/typescript@4.7.4/lib/lib.dom.d.ts"
15-
{:ok, source} = ComponentsGuide.Research.Source.text_at(url)
1614
start = System.monotonic_time()
1715
types = Typescript.Parser.parse(source)
1816
duration = System.monotonic_time() - start
19-
IO.inspect(as_ms.(duration), label: "parse")
17+
IO.inspect(as_ms.(duration), label: "parse types")
2018
types_sources = Typescript.Parser.extract_line_ranges(source, types)
2119
duration = System.monotonic_time() - start
22-
IO.inspect(as_ms.(duration), label: "parse + extract")
20+
IO.inspect(as_ms.(duration), label: "parse + extract types")
2321

24-
IO.inspect(types |> Enum.map(fn %{__struct__: type} -> type end) |> Enum.uniq(),
25-
label: "types"
26-
)
22+
Enum.zip_with(types, types_sources, fn type, type_source ->
23+
%{name: type.name, doc: type.doc, source: type_source}
24+
end)
25+
end
2726

28-
results =
29-
Enum.zip_with(types, types_sources, fn type, type_source ->
30-
%{name: type.name, doc: type.doc, source: type_source}
31-
end)
27+
def show(conn, %{"section" => "dom-types"}) do
28+
url = "https://cdn.jsdelivr.net/npm/typescript@4.7.4/lib/lib.dom.d.ts"
29+
{:ok, source} = ComponentsGuide.Research.Source.text_at(url)
30+
results = process_typescript_source(source)
3231

3332
conn
3433
|> assign(:page_title, "Search DOM Types")
35-
|> render("dom-types.html", results: results)
34+
|> render("typescript.html", results: results)
35+
end
36+
37+
def show(conn, %{"section" => "css-types"}) do
38+
url = "https://cdn.jsdelivr.net/npm/csstype@3.1.0/index.d.ts"
39+
{:ok, source} = ComponentsGuide.Research.Source.text_at(url)
40+
IO.inspect(source)
41+
results = process_typescript_source(source)
42+
IO.inspect(results)
43+
44+
conn
45+
|> assign(:page_title, "Search CSS Types")
46+
|> render("typescript.html", results: results)
47+
end
48+
49+
def show(conn, %{"section" => "react-types"}) do
50+
url = "https://cdn.jsdelivr.net/npm/@types/react@18.0.18/index.d.ts"
51+
{:ok, source} = ComponentsGuide.Research.Source.text_at(url)
52+
53+
source =
54+
source
55+
|> String.replace("declare namespace React {", "", global: false)
56+
|> String.replace("\n ", "\n")
57+
# |> String.trim_trailig("declare namespace React {")
58+
59+
results = process_typescript_source(source)
60+
61+
conn
62+
|> assign(:page_title, "Search React Types")
63+
|> render("typescript.html", results: results)
3664
end
3765

3866
# TODO: add Tailwind search e.g. "ml-4" or "ml-[5rem]" and see what is produced

lib/components_guide_web/templates/layout/root.html.heex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,21 @@
4949
<% end %>
5050

5151
<!-- Prism syntax highlighting -->
52+
<script>
53+
window.Prism = window.Prism || {};
54+
Prism.manual = true;
55+
</script>
5256
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/components/prism-core.min.js" integrity="sha512-hqRrGU7ys5tkcqxx5FIZTBb7PkO2o3mU6U5+qB9b55kgMlBUT4J2wPwQfMCxeJW1fC8pBxuatxoH//z0FInhrA==" crossorigin="anonymous"></script>
5357
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-ROhjG07IRaPZsryG77+MVyx3ZT5q3sGEGENoGItwc9xgvx+dl+s3D8Ob1zPdbl/iKklMKp7uFemLJFDRw0bvig==" crossorigin="anonymous"></script>
5458
<!--<link href="https://cdn.jsdelivr.net/gh/PrismJS/prism-themes@8a0b50bd5cef0c86154c22b8b17d97348323b343/themes/prism-a11y-dark.css" rel="stylesheet">-->
5559
<link rel="stylesheet" href="https://unpkg.com/prism-theme-night-owl@1.4.0/build/style.css">
5660
<script>
61+
const skipHighlightAll = document.querySelectorAll('skip-syntax-highlighting').length > 0;
5762
//document.querySelectorAll('.post.category-javascript pre code').forEach(el => el.classList.add('language-jsx'));
58-
window.Prism.highlightAll();
63+
if (!skipHighlightAll) {
64+
console.log("Highlighting all with Prism")
65+
window.Prism.highlightAll();
66+
}
5967
</script>
6068
</body>
6169
</html>

lib/components_guide_web/templates/research/dom-types.html.heex

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)