Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File parser #744

Merged
merged 5 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,62 @@ Class {
#package : 'Microdown-ParentChildrenChecker'
}

{ #category : 'visiting main API' }
MicParentChildrenChecker >> check: anElement [
"Check if the parent of the element correctly includes this element as a child"

anElement parent
ifNil: [
anElement class = MicRootBlock
ifFalse: [ orphanList add: anElement ]
ifTrue: [ anElement children do: [ :each | self check: each ] ] ]
ifNotNil: [ :p | "We cannot identify bad parent that are refered by child not in the children
list, because by construction the algo only considers the children of an element).
(p children includes: anElement) ifFalse: [ self addParent: p ]."
p children do: [ :child |
child parent = p ifFalse: [ confusedKids add: child ] ].

anElement children do: [ :each | self check: each ] ]
{ #category : 'accessing' }
MicParentChildrenChecker >> check: anElement [
"Check if the parent of the element correctly includes this element as a child and if the element's parent pointer is correct."

anElement parent
ifNil: [
"Check if the root element is indeed supposed to have no parent"
(anElement class = MicRootBlock)
ifFalse: [
"If it's not a root, it should have a parent"
orphanList add: anElement
].
"Recursively check all children of the current element"
anElement children do: [ :each | self check: each ]
]
ifNotNil: [ :p |
"Check if the parent’s list of children actually includes this element"
(p children includes: anElement)
ifFalse: [
confusedKids add: anElement
].

"Recursively check all children of the current element"
anElement children do: [ :child |
self check: child
]
].
]

{ #category : 'accessing' }
MicParentChildrenChecker >> confusedKids [
MicParentChildrenChecker >> confusedKids [

^ confusedKids


]

{ #category : 'visiting main API' }
MicParentChildrenChecker >> initialize [
{ #category : 'accessing' }
MicParentChildrenChecker >> initialize [

super initialize.
orphanList := OrderedCollection new.
confusedKids := OrderedCollection new


]

{ #category : 'testing' }
MicParentChildrenChecker >> isOk [
{ #category : 'accessing' }
MicParentChildrenChecker >> isOk [

^ (orphanList isEmpty and: [ confusedKids isEmpty ])

^ confusedKids isEmpty and:
(orphanList isEmpty and: [ confusedKids isEmpty ])
]

{ #category : 'accessing' }
MicParentChildrenChecker >> orphanList [
MicParentChildrenChecker >> orphanList [
^orphanList

]
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,162 @@ Class {
#package : 'Microdown-ParentChildrenChecker'
}

{ #category : 'tests' }
{ #category : 'accessing' }
MicParentChildrenCheckerTest >> document [
^ Microdown parse: '#Microdown is quite cool

Here is some code

```language=Pharo&caption=Beautiful&anchor=Fig1
1000 factorial / 999 factorial
```

Here is a figure and a link: [http://pharo.org](http://pharo.org).

![Pharologo](https://files.pharo.org/media/logo/logo.png size=80&anchor=figLogo.)



Here is a list:
- item 1
1. sub item 1
3. sub item 2
- item 2


**Bold**, _italic_, `monospace`

In Pharo, Microdown supports hyperlinks to:
- classes e.g., `Point`,
- methodes e.g., `Point class`, `Point>>#setX:setY:`, and
- packages e.g., `#''Microdown-Tests''` (for packages).

You can edit this file clicking on `ClySyntaxHelpMorph>>#rawMicrodownSyntax`.'.


]

{ #category : 'accessing' }
MicParentChildrenCheckerTest >> testComplexDocumentWithConfusedKidsAndOrphans [
| checker document child1 child2 wrongChild orphan |

"Initialize the parent-children relationship checker"
checker := MicParentChildrenChecker new.

"Parse a complex Microdown document"
document := Microdown parse: '# Microdown Documentation Example

Welcome to the **Microdown Documentation**. This document serves as a tutorial and reference for creating rich markdown documents with various formatting options in Microdown.

## Introduction

Microdown allows you to write documentation directly in your Pharo environment, supporting standard markdown syntax and Pharo-specific enhancements.

### What is Markdown?

Markdown is a lightweight markup language with plain-text formatting syntax. It is designed so that it can be converted to HTML and many other formats.

## Text Formatting

Text in Microdown can be formatted in several ways:

- **Bold**: `**Bold text**` renders as **Bold text**
- _Italic_: `*Italic text*` renders as _Italic text_
- **_Combined Emphasis_**: `**_Bold and italic_**` renders as **_Bold and italic_**

## Lists

Microdown supports both ordered and unordered lists.

### Unordered List

- Item 1
- Item 2
- Subitem 2.1
- Subitem 2.2

### Ordered List

1. First item
2. Second item
1. Subitem 2.1
2. Subitem 2.2

## Links and Images

### Linking

This is how you create a [link](http://example.com).

### Images

Here''s how you embed an image:

![Alt text for the image](http://example.com/image.png)

## Code Blocks

You can add code blocks for code snippets, which are especially useful for programming documentation:

```smalltalk
Transcript show: ''Hello, world!'.

"Create confused kids: Misassign a sub-subheading to a different subheading"
child1 := document children second children second. "Assuming this is Sub-Subheading 1.1"
child2 := document children third. "Assuming this is Subheading 2"
wrongChild := child1 children first. "Content of Sub-Subheading 1.1"
wrongChild basicParent: child2. "Incorrectly setting it to Subheading 2"

"Create an orphan: Detach a sub-subheading without assigning a new parent"
orphan := document children third children last. "Assuming this is Sub-Subheading 2.2"
orphan basicParent: nil.

"Verify incorrect setups before checking"
self assert: (wrongChild parent = child2).
self assert: orphan parent isNil.

"Run the checker on the modified document"
checker check: document.

"Assert that the checker identifies the document as not OK"
self deny: checker isOk


]

{ #category : 'accessing' }
MicParentChildrenCheckerTest >> testDocumentWithConfusedKids [
| checker document child1 child2 |

"Initialize the parent-children relationship checker"


"Parse a simple Microdown document"
checker := MicParentChildrenChecker new.
document := Microdown parse: '# Microdown is quite cool
## Subheading 1
Microdown enables rich text formatting.
## Subheading 2
It’s also quite easy to use.'.

"Manually access children and reassign to create a 'confused kid'"
child1 := document children first.
child2 := document children second children first .
child2 basicParent: child1 .



"Run the checker on the modified document"
checker check: document.

self deny: checker isOk .

"Assert that the checker identifies the document as not OK due to confused relationships"


]

{ #category : 'tests' }
MicParentChildrenCheckerTest >> testSimpleDocumentIsWellFormed [
{ #category : 'accessing' }
MicParentChildrenCheckerTest >> testSimpleDocumentIsWellFormed [

| checker |
checker := MicParentChildrenChecker new.
checker check: self document.
self assert: checker isOk
self deny: ( checker isOk)

]

{ #category : 'tests' }
MicParentChildrenCheckerTest >> testSimpleDocumentWithOrphans [
{ #category : 'accessing' }
MicParentChildrenCheckerTest >> testSimpleDocumentWithOrphans [

| brokenDocument visitor orphan |
visitor := MicParentChildrenChecker new.
Expand All @@ -61,4 +172,5 @@ MicParentChildrenCheckerTest >> testSimpleDocumentWithOrphans [
visitor check: brokenDocument.

self deny: visitor isOk

]
10 changes: 10 additions & 0 deletions src/Microdown/MicRootBlock.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ MicRootBlock >> canConsumeLine: line [
^ true
]

{ #category : 'visiting' }
MicRootBlock >> fromFile [ " retieve "
^ self propertyAt: #file .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the last period is not needed.

]

{ #category : 'visiting' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in visiting

MicRootBlock >> fromFile: aFile [ " put file object in the root"
self propertyAt: #file put: aFile .
]

{ #category : 'accessing' }
MicRootBlock >> indent [
^0
Expand Down
16 changes: 16 additions & 0 deletions src/Microdown/Microdown.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ Microdown class >> parse: aStreamOrString [
^ self new parse: aStreamOrString
]

{ #category : 'facade' }
Microdown class >> parseFile: aFile [

^ self new parseFile: aFile
]

{ #category : 'facade' }
Microdown class >> resolveDocument: document withBase: base [
"resolve all relative urls in document with respect to the absolute uri
Expand Down Expand Up @@ -146,6 +152,16 @@ Microdown >> parse: aStreamOrString [
^ MicrodownParser parse: aStreamOrString
]

{ #category : 'facade' }
Microdown >> parseFile: aFile [

|root|
root := MicrodownParser parse:(aFile contents) .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse: (aFile contents).

No extra space

root fromFile: aFile .
^ root .

]

{ #category : 'facade' }
Microdown >> render: aStringOrDoc [
"Facade method to render a microdown string to Text"
Expand Down
30 changes: 30 additions & 0 deletions src/microdown-fileParser/FileParser.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Class {
#name : 'FileParser',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename your class FromFileTest?
tx

#superclass : 'TestCase',
#category : 'microdown-fileParser',
#package : 'microdown-fileParser'
}

{ #category : 'as yet unclassified' }
FileParser >> testCreatingFileAndParsingtheContent [

| file root |
file := (FileSystem workingDirectory / 'myFile.txt') asFileReference.
file ensureCreateFile.



file writeStreamDo: [ :stream | stream nextPutAll: '
### title
@first

just talking about somthing @*first*@ ' ] .

root := Microdown parseFile: file contents .

self assert: (root isKindOf: MicRootBlock ) .
self assert: root fromFile equals: file contents .
file ensureDelete .


]
1 change: 1 addition & 0 deletions src/microdown-fileParser/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : 'microdown-fileParser' }
Loading