Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
9f0bba1b
Commit
9f0bba1b
authored
4 months ago
by
Remi Lazarini
Browse files
Options
Downloads
Patches
Plain Diff
[Ivette] markdown : refacto component
parent
2c23dbb6
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ivette/src/dome/renderer/text/markdown.tsx
+43
-84
43 additions, 84 deletions
ivette/src/dome/renderer/text/markdown.tsx
with
43 additions
and
84 deletions
ivette/src/dome/renderer/text/markdown.tsx
+
43
−
84
View file @
9f0bba1b
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
/* ************************************************************************ */
/* ************************************************************************ */
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
ReactMarkdown
,
{
Components
,
Options
}
from
'
react-markdown
'
;
import
ReactMarkdown
,
{
Options
}
from
'
react-markdown
'
;
import
{
classes
}
from
'
dome/misc/utils
'
;
import
{
classes
}
from
'
dome/misc/utils
'
;
import
{
Icon
}
from
'
dome/controls/icons
'
;
import
{
Icon
}
from
'
dome/controls/icons
'
;
...
@@ -38,82 +38,67 @@ export const iconTag: Pattern = {
...
@@ -38,82 +38,67 @@ export const iconTag: Pattern = {
}
}
};
};
class
Counter
{
private
val
:
number
=
0
;
increment
():
number
{
return
this
.
val
++
;
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Replacement function
// --- Replacement function
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/**
/**
* Replace all tag in
the text
.
* Replace all tag in
children
.
* This function doesn't replace any tags added by a previous replacement.
* This function doesn't replace any tags added by a previous replacement.
*/
*/
function
replaceTagsByElement
(
text
:
string
,
counter
:
Counter
,
patterns
?:
Pattern
[],
):
(
string
|
JSX
.
Element
|
null
)[]
{
if
(
!
patterns
||
patterns
.
length
<
1
)
return
[
text
];
type
Content
=
string
|
JSX
.
Element
|
null
;
let
newContent
:
(
Content
|
Content
[])[]
=
[
text
];
let
match
;
let
lastIndex
:
number
;
patterns
.
forEach
(({
pattern
,
replace
})
=>
{
newContent
=
newContent
.
flat
();
newContent
.
slice
().
forEach
((
content
,
i
)
=>
{
if
(
typeof
content
===
"
string
"
)
{
const
contentTab
:
(
string
|
JSX
.
Element
|
null
)[]
=
[];
lastIndex
=
0
;
while
((
match
=
pattern
.
exec
(
content
))
!==
null
)
{
if
(
match
.
index
>
lastIndex
)
{
contentTab
.
push
(
content
.
slice
(
lastIndex
,
match
.
index
));
}
contentTab
.
push
(
replace
(
counter
.
increment
(),
match
));
lastIndex
=
pattern
.
lastIndex
;
}
if
(
lastIndex
<
content
.
length
)
{
contentTab
.
push
(
content
.
slice
(
lastIndex
));
}
newContent
.
splice
(
i
,
1
,
contentTab
);
}
});
});
return
newContent
.
flat
();
}
function
replaceTags
(
function
replaceTags
(
children
:
React
.
ReactNode
,
children
:
React
.
ReactNode
,
patterns
:
Pattern
[],
patterns
:
Pattern
[],
counter
:
Counter
):
React
.
ReactNode
{
):
React
.
ReactNode
{
if
(
patterns
.
length
<
1
)
return
children
;
const
buffer
:
React
.
ReactNode
[]
=
[];
let
counter
=
0
;
const
childrenTab
=
React
.
Children
.
toArray
(
children
);
const
childrenTab
=
React
.
Children
.
toArray
(
children
);
const
newContent
=
childrenTab
.
map
((
child
)
=>
{
const
makeReplace
=
(
text
:
string
,
index
:
number
):
void
=>
{
if
(
index
>=
patterns
.
length
)
{
buffer
.
push
(
text
);
return
;
}
const
{
pattern
,
replace
}
=
patterns
[
index
];
let
match
;
let
lastIndex
=
0
;
while
((
match
=
pattern
.
exec
(
text
))
!==
null
)
{
if
(
match
.
index
>
lastIndex
)
{
makeReplace
(
text
.
slice
(
lastIndex
,
match
.
index
),
index
+
1
);
}
buffer
.
push
(
replace
(
counter
++
,
match
));
lastIndex
=
pattern
.
lastIndex
;
}
if
(
lastIndex
<
text
.
length
)
{
makeReplace
(
text
.
slice
(
lastIndex
),
index
+
1
);
}
};
/** makeReplace is applied if child is a string,
* otherwise it is pushed into the buffer
*/
childrenTab
.
forEach
((
child
)
=>
{
if
(
typeof
child
===
'
string
'
)
{
if
(
typeof
child
===
'
string
'
)
{
return
r
eplace
TagsByElement
(
child
,
counter
,
patterns
.
slice
()
);
return
makeR
eplace
(
child
,
0
);
}
}
return
child
;
return
buffer
.
push
(
child
)
;
});
});
return
newContent
;
return
buffer
;
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Markdown component
// --- Markdown component
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
type
tagHtmlList
=
[
k
:
keyof
Components
,
v
:
keyof
Components
][]
interface
MarkdownProps
{
interface
MarkdownProps
{
/** classes for Markdown component */
/** classes for Markdown component */
className
?:
string
;
className
?:
string
;
/** html tag of the markdown to be processed and possible replacement */
/** Tab of patterns */
htmlTag
?:
tagHtmlList
;
patterns
?:
Pattern
[];
/** Tab of tag replacement */
pattern
?:
Pattern
[];
/** Children */
/** Children */
children
?:
string
|
null
;
children
?:
string
|
null
;
}
}
...
@@ -121,41 +106,15 @@ interface MarkdownProps {
...
@@ -121,41 +106,15 @@ interface MarkdownProps {
export
function
Markdown
(
export
function
Markdown
(
props
:
MarkdownProps
props
:
MarkdownProps
):
JSX
.
Element
{
):
JSX
.
Element
{
const
{
className
,
pattern
,
htmlTag
,
children
}
=
props
;
const
{
className
,
pattern
s
,
children
}
=
props
;
const
markdownClasses
=
classes
(
const
markdownClasses
=
classes
(
"
dome-xMarkdown
"
,
"
dome-pages
"
,
"
dome-xMarkdown
"
,
"
dome-pages
"
,
className
className
,
);
);
const
counter
=
new
Counter
();
const
options
:
Options
=
{
className
:
markdownClasses
};
const
transformChildren
=
(
c
:
React
.
ReactNode
):
React
.
ReactNode
=>
{
if
(
patterns
&&
patterns
.
length
>
0
)
options
.
components
=
{
return
!
pattern
?
c
:
replaceTags
(
c
,
pattern
,
counter
);
p
:
({
children
})
=>
<
div
>
{
replaceTags
(
children
,
patterns
)
}
</
div
>,
};
li
:
({
children
})
=>
<
li
>
{
replaceTags
(
children
,
patterns
)
}
</
li
>
const
getComponentsOption
=
():
Components
|
null
=>
{
if
(
!
htmlTag
)
return
null
;
const
getDynamicElement
=
(
tagName
:
keyof
JSX
.
IntrinsicElements
,
children
:
React
.
ReactNode
):
JSX
.
Element
=>
{
const
Tag
=
tagName
;
return
<
Tag
>
{
children
}
</
Tag
>;
};
const
component
=
[];
for
(
const
[
key
,
val
]
of
htmlTag
)
{
component
.
push
([
key
,
({
children
}:
{
children
:
React
.
ReactNode
;
})
=>
getDynamicElement
(
val
,
transformChildren
(
children
))]);
}
return
Object
.
fromEntries
(
component
);
};
const
options
:
Options
=
{
className
:
markdownClasses
,
components
:
getComponentsOption
()
};
};
return
<
ReactMarkdown
{
...
options
}
>
{
children
}
</
ReactMarkdown
>;
return
<
ReactMarkdown
{
...
options
}
>
{
children
}
</
ReactMarkdown
>;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment