pnote_client 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +98 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/config.json +26 -0
  12. data/exe/pnote_to_json +64 -0
  13. data/lib/pnote_client/converters/hml_to_pnote_converter.rb +195 -0
  14. data/lib/pnote_client/converters/pnote_to_json_converter.rb +96 -0
  15. data/lib/pnote_client/display/console_display.rb +37 -0
  16. data/lib/pnote_client/documents/hml/binary_item.rb +20 -0
  17. data/lib/pnote_client/documents/hml/char.rb +27 -0
  18. data/lib/pnote_client/documents/hml/equation.rb +33 -0
  19. data/lib/pnote_client/documents/hml/image.rb +28 -0
  20. data/lib/pnote_client/documents/hml/paragraph.rb +84 -0
  21. data/lib/pnote_client/documents/hml/paragraph_reader.rb +29 -0
  22. data/lib/pnote_client/documents/hml/rectangle.rb +39 -0
  23. data/lib/pnote_client/documents/hml/style.rb +21 -0
  24. data/lib/pnote_client/documents/hml/table.rb +55 -0
  25. data/lib/pnote_client/documents/hml/table_cell.rb +49 -0
  26. data/lib/pnote_client/documents/hml/table_row.rb +34 -0
  27. data/lib/pnote_client/documents/hml.rb +60 -0
  28. data/lib/pnote_client/documents/pnote/chapter.rb +27 -0
  29. data/lib/pnote_client/documents/pnote/concept.rb +26 -0
  30. data/lib/pnote_client/documents/pnote/exercise.rb +10 -0
  31. data/lib/pnote_client/documents/pnote/image.rb +16 -0
  32. data/lib/pnote_client/documents/pnote/practice.rb +25 -0
  33. data/lib/pnote_client/documents/pnote/problem.rb +50 -0
  34. data/lib/pnote_client/documents/pnote/sub_chapter.rb +32 -0
  35. data/lib/pnote_client/documents/pnote/teacher_comment.rb +22 -0
  36. data/lib/pnote_client/documents/pnote.rb +20 -0
  37. data/lib/pnote_client/utils/string_util.rb +10 -0
  38. data/lib/pnote_client/version.rb +3 -0
  39. data/lib/pnote_client.rb +4 -0
  40. data/pnote_client.gemspec +35 -0
  41. metadata +155 -0
@@ -0,0 +1,33 @@
1
+ require 'hwp_script_to_latex/converter'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Hml
6
+ class Equation
7
+ # Textable Element
8
+
9
+ def self.from_tag(eq_tag)
10
+ script = eq_tag.xpath("SCRIPT")[0].content
11
+ return self.new(script)
12
+ end
13
+
14
+ def initialize(script)
15
+ @script = script
16
+ @script_converter = ::HwpScriptToLatex::Converter.new
17
+ end
18
+
19
+ def content
20
+ if @script_converter
21
+ return @script_converter.convert(@script, math_mode: true)
22
+ else
23
+ return @script
24
+ end
25
+ end
26
+
27
+ def textable?
28
+ return true
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Hml
4
+ class Image
5
+
6
+ def self.from_tag(image_tag)
7
+ bin_item_id = image_tag['BinItem']
8
+
9
+ return self.new(bin_item_id)
10
+ end
11
+
12
+ attr_reader :bin_item_id
13
+
14
+ def initialize(bin_item_id)
15
+ @bin_item_id = bin_item_id
16
+ end
17
+
18
+ def content
19
+ return "![image](#{@bin_item_id})"
20
+ end
21
+
22
+ def textable?
23
+ return true
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,84 @@
1
+ require 'pnote_client/documents/hml/char'
2
+ require 'pnote_client/documents/hml/equation'
3
+ require 'pnote_client/documents/hml/table'
4
+ require 'pnote_client/documents/hml/rectangle'
5
+ require 'pnote_client/documents/hml/image'
6
+
7
+ module PnoteClient
8
+ module Documents
9
+ class Hml
10
+ class Paragraph
11
+ # Textable Element
12
+
13
+ def self.from_tag(pg_tag)
14
+ paragraph = self.new(
15
+ style_id: pg_tag['Style'],
16
+ shape_id: pg_tag['ParaShape']
17
+ )
18
+
19
+ # Add Elements
20
+ children = pg_tag.xpath("TEXT/CHAR|TEXT/EQUATION|TEXT/ENDNOTE|TEXT/FOOTNOTE|TEXT/TABLE|TEXT/RECTANGLE|TEXT/PICTURE/IMAGE")
21
+ children.each do |child|
22
+ if child.name == 'CHAR'
23
+ paragraph.add_element(Char.from_tag(child))
24
+ elsif child.name == 'EQUATION'
25
+ paragraph.add_element(Equation.from_tag(child))
26
+ elsif child.name == 'ENDNOTE'
27
+ pg_tags = child.xpath("PARALIST/P")
28
+ pg_tags.map {|pg_tag| self.from_tag(pg_tag)}.each do |endnote_paragraph|
29
+ paragraph.add_endnote_paragraph(endnote_paragraph)
30
+ end
31
+ elsif child.name == 'FOOTNOTE'
32
+ pg_tags = child.xpath("PARALIST/P")
33
+ pg_tags.map {|pg_tag| self.from_tag(pg_tag)}.each do |footnote_paragraph|
34
+ paragraph.add_footnote_paragraph(footnote_paragraph)
35
+ end
36
+ elsif child.name == 'TABLE'
37
+ table = Table.from_tag(child)
38
+ paragraph.add_element(table)
39
+ elsif child.name == 'RECTANGLE'
40
+ rectangle = Rectangle.from_tag(child)
41
+ paragraph.add_element(rectangle)
42
+ elsif child.name = 'IMAGE'
43
+ image = Image.from_tag(child)
44
+ paragraph.add_element(image)
45
+ end
46
+ end
47
+
48
+ return paragraph
49
+ end
50
+
51
+ attr_reader :style_id, :shape_id
52
+ attr_reader :endnote_paragraphs, :footnote_paragraphs
53
+
54
+ def initialize(style_id:, shape_id:)
55
+ @style_id = style_id
56
+ @shape_id = shape_id
57
+ @endnote_paragraphs = []
58
+ @footnote_paragraphs = []
59
+ @elements = []
60
+ end
61
+
62
+ def add_element(element)
63
+ @elements << element
64
+ end
65
+
66
+ def add_endnote_paragraph(new_paragraph)
67
+ @endnote_paragraphs << new_paragraph
68
+ end
69
+
70
+ def add_footnote_paragraph(new_paragraph)
71
+ @footnote_paragraphs << new_paragraph
72
+ end
73
+
74
+ def content
75
+ return @elements.select{|element| element.textable?}.map {|element| element.content}.join
76
+ end
77
+
78
+ def textable?
79
+ return true
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,29 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Hml
4
+ class ParagraphReader
5
+
6
+ def initialize(paragraphs)
7
+ @paragraphs = paragraphs
8
+ end
9
+
10
+ def next_paragraph
11
+ current_paragraph = nil
12
+ prev_paragraph = nil
13
+ @paragraphs.each_with_index do |paragraph, index|
14
+ current_paragraph = paragraph
15
+ yield(current_paragraph, prev_paragraph, is_continuous_paragraph?(current_paragraph, prev_paragraph), index) if block_given?
16
+ prev_paragraph = paragraph
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def is_continuous_paragraph?(paragraph1, paragraph2)
23
+ return false if paragraph1.nil? || paragraph2.nil?
24
+ return paragraph1.style_id == paragraph2.style_id
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ require 'pnote_client/documents/hml/paragraph'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Hml
6
+ class Rectangle
7
+
8
+ def self.from_tag(rect_tag)
9
+ rect = self.new
10
+
11
+ pg_tags = rect_tag.xpath("DRAWINGOBJECT/DRAWTEXT/PARALIST/P")
12
+ pg_tags.each do |pg_tag|
13
+ rect.add_paragraph(Paragraph.from_tag(pg_tag))
14
+ end
15
+
16
+ return rect
17
+ end
18
+
19
+ attr_reader :paragraph
20
+
21
+ def initialize
22
+ @paragraphs = []
23
+ end
24
+
25
+ def add_paragraph(new_paragraph)
26
+ @paragraphs << new_paragraph
27
+ end
28
+
29
+ def content
30
+ @paragraphs.map {|pg| pg.content}.join("\n")
31
+ end
32
+
33
+ def textable?
34
+ return true
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Hml
4
+ class Style
5
+ def self.from_tag(style_tag)
6
+ style_id = style_tag['Id']
7
+ style_name = style_tag['Name']
8
+
9
+ return self.new(style_id, style_name)
10
+ end
11
+
12
+ attr_reader :id, :name
13
+
14
+ def initialize(id, name)
15
+ @id = id
16
+ @name = name
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,55 @@
1
+ require 'pnote_client/documents/hml/table_row'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Hml
6
+ class Table
7
+
8
+ def self.from_tag(table_tag)
9
+ row_count = table_tag['RowCount']
10
+ col_count = table_tag['ColCount']
11
+
12
+ table = self.new(row_count: row_count.to_i, col_count: col_count.to_i)
13
+ row_tags = table_tag.xpath("ROW")
14
+ row_tags.each do |row_tag|
15
+ table.add_row(TableRow.from_tag(row_tag))
16
+ end
17
+
18
+ return table
19
+ end
20
+
21
+ attr_reader :row_count, :col_count, :rows
22
+
23
+ def initialize(row_count: 0, col_count: 0)
24
+ @row_count = row_count
25
+ @col_count = col_count
26
+ @rows = []
27
+ end
28
+
29
+ def add_row(row)
30
+ @rows << row
31
+ end
32
+
33
+ def content
34
+ json = {
35
+ col_count: @col_count,
36
+ row_count: @row_count,
37
+ rows: rows_content
38
+ }.to_json
39
+
40
+ return "![table](#{json})"
41
+ end
42
+
43
+ def textable?
44
+ return true
45
+ end
46
+
47
+ private
48
+
49
+ def rows_content
50
+ @rows.map {|row| row.content}
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,49 @@
1
+ require 'pnote_client/documents/hml/paragraph'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Hml
6
+ class TableCell
7
+ def self.from_tag(cell_tag)
8
+ row_span = cell_tag['RowSpan']
9
+ col_span = cell_tag['ColSpan']
10
+
11
+ cell = self.new(row_span: row_span.to_i, col_span: col_span.to_i)
12
+
13
+ pg_tags = cell_tag.xpath("PARALIST/P")
14
+ pg_tags.each do |pg_tag|
15
+ cell.add_paragraph(Paragraph.from_tag(pg_tag))
16
+ end
17
+
18
+ return cell
19
+ end
20
+
21
+ attr_reader :row_span, :col_span, :paragraphs
22
+
23
+ def initialize(row_span: 1, col_span: 1)
24
+ @row_span = row_span
25
+ @col_span = col_span
26
+ @paragraphs = []
27
+ end
28
+
29
+ def add_paragraph(new_paragraph)
30
+ @paragraphs << new_paragraph
31
+ end
32
+
33
+ def content
34
+ return {
35
+ row_span: @row_span,
36
+ col_span: @col_span,
37
+ content: paragraphs_content
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ def paragraphs_content
44
+ return @paragraphs.map {|pg| pg.content}.join("\n")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ require 'pnote_client/documents/hml/table_cell'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Hml
6
+ class TableRow
7
+ def self.from_tag(row_tag)
8
+ row = self.new
9
+
10
+ cell_tags = row_tag.xpath("CELL")
11
+ cell_tags.each do |cell_tag|
12
+ row.add_cell(TableCell.from_tag(cell_tag))
13
+ end
14
+
15
+ return row
16
+ end
17
+
18
+ attr_reader :cells
19
+
20
+ def initialize
21
+ @cells = []
22
+ end
23
+
24
+ def add_cell(cell)
25
+ @cells << cell
26
+ end
27
+
28
+ def content
29
+ return @cells.map {|cell| cell.content}
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,60 @@
1
+ require 'nokogiri'
2
+ require 'pnote_client/documents/hml/style'
3
+ require 'pnote_client/documents/hml/paragraph'
4
+ require 'pnote_client/documents/hml/binary_item'
5
+
6
+ class InvalidXMLError < StandardError; end
7
+
8
+ module PnoteClient
9
+ module Documents
10
+ class Hml
11
+ attr_reader :styles, :paragraphs, :bin_items
12
+
13
+ def self.parse_from_file(file_path)
14
+ file = File.open(file_path)
15
+ hml_content = file.read
16
+ file.close
17
+
18
+ return self.parse(hml_content)
19
+ end
20
+
21
+ def self.parse(hml_content)
22
+ styles = []
23
+ paragraphs = []
24
+ bin_items = []
25
+ doc = Nokogiri::XML(hml_content)
26
+ unless doc.errors.empty?
27
+ raise InvalidXMLError.new(doc.errors.first.message)
28
+ end
29
+
30
+ # 빈 TEXT 삭제
31
+ doc.xpath("//P[TEXT[not(node())]]").each do |p|
32
+ p.remove
33
+ end
34
+
35
+ style_tags = doc.xpath("//STYLELIST/STYLE")
36
+ style_tags.each do |style_tag|
37
+ styles << Style.from_tag(style_tag)
38
+ end
39
+
40
+ pg_tags = doc.xpath("//SECTION/P")
41
+ pg_tags.each do |pg_tag|
42
+ paragraphs << Paragraph.from_tag(pg_tag)
43
+ end
44
+
45
+ bin_item_tags = doc.xpath("//BINITEM")
46
+ bin_item_tags.each do |bin_item_tag|
47
+ bin_items << BinaryItem.new(bin_item_tag, doc)
48
+ end
49
+
50
+ return self.new(styles: styles, paragraphs: paragraphs, bin_items: bin_items)
51
+ end
52
+
53
+ def initialize(styles: [], paragraphs: [], bin_items: [])
54
+ @styles = styles
55
+ @paragraphs = paragraphs
56
+ @bin_items = bin_items
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,27 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Pnote
4
+ class Chapter
5
+ attr_reader :title, :sub_chapters, :practices
6
+
7
+ def initialize
8
+ @title = nil
9
+ @sub_chapters = []
10
+ @practices = []
11
+ end
12
+
13
+ def set_title(title)
14
+ @title = title
15
+ end
16
+
17
+ def add_sub_chapter(new_sub_chapter)
18
+ @sub_chapters << new_sub_chapter
19
+ end
20
+
21
+ def add_practice(new_practice)
22
+ @practices << new_practice
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require 'pnote_client/utils/string_util'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Pnote
6
+ class Concept
7
+ include Utils::StringUtil
8
+
9
+ attr_reader :title, :content
10
+
11
+ def initialize
12
+ @title = nil
13
+ @content = nil
14
+ end
15
+
16
+ def set_title(title)
17
+ @title = title
18
+ end
19
+
20
+ def add_content(content)
21
+ @content = add_line(@content, content)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ require 'pnote_client/documents/pnote/problem'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Pnote
6
+ class Exercise < Problem
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Pnote
4
+ class Image
5
+ attr_reader :id, :format, :size, :raw_data
6
+
7
+ def initialize(id, format, size, raw_data)
8
+ @id = id
9
+ @format = format
10
+ @size = size
11
+ @raw_data = raw_data
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ require 'pnote_client/documents/pnote/problem'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Pnote
6
+ class Practice < Problem
7
+ attr_accessor :teacher_comments, :tip
8
+
9
+ def initialize
10
+ super
11
+ @teacher_comments = []
12
+ @tip = nil
13
+ end
14
+
15
+ def add_teacher_comment(new_teacher_comment)
16
+ @teacher_comments << new_teacher_comment
17
+ end
18
+
19
+ def add_tip_line(new_line)
20
+ @tip = add_line(@tip, new_line)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ require 'pnote_client/utils/string_util'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Pnote
6
+ # 연습문제(Exercise)와 실전문제(Practice)의 부모 클래스
7
+ # 중복되는 부분을 재사용하기위해 만듦
8
+ class Problem
9
+ include Utils::StringUtil
10
+
11
+ attr_accessor :question, :explaination
12
+
13
+ def initialize
14
+ @question = nil
15
+ @answer = nil
16
+ @explaination = nil
17
+ @choice = nil
18
+ end
19
+
20
+ def add_question_line(new_line)
21
+ @question = add_line(@question, new_line)
22
+ end
23
+
24
+ def add_answer_line(new_line)
25
+ @answer = add_line(@answer, new_line)
26
+ end
27
+
28
+ def add_explaination_line(new_line)
29
+ @explaination = add_line(@explaination, new_line)
30
+ end
31
+
32
+ def add_choice_line(new_line)
33
+ @choice = add_line(@choice, new_line)
34
+ end
35
+
36
+ def answer
37
+ return nil if @answer.nil?
38
+ return @answer.match(/\s*\[정답\]\s*(.*)/).to_a[1].strip
39
+ end
40
+
41
+ def choices
42
+ return [] if @choice.nil?
43
+
44
+ choice_number_pattern = /①|②|③|④|⑤/
45
+ return @choice.split(choice_number_pattern).reject {|el| el.empty?}.map {|el| el.strip}
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Pnote
4
+ class SubChapter
5
+ attr_reader :title, :concepts, :exercises, :practices
6
+
7
+ def initialize
8
+ @title = nil
9
+ @concepts = []
10
+ @exercises = []
11
+ @practices = []
12
+ end
13
+
14
+ def set_title(title)
15
+ @title = title
16
+ end
17
+
18
+ def add_concept(new_concept)
19
+ @concepts << new_concept
20
+ end
21
+
22
+ def add_exercise(new_exercise)
23
+ @exercises << new_exercise
24
+ end
25
+
26
+ def add_practice(new_practice)
27
+ @practices << new_practice
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'pnote_client/utils/string_util'
2
+
3
+ module PnoteClient
4
+ module Documents
5
+ class Pnote
6
+ class TeacherComment
7
+ include Utils::StringUtil
8
+
9
+ attr_accessor :index, :content
10
+
11
+ def initialize(index)
12
+ @index = index
13
+ @content = nil
14
+ end
15
+
16
+ def add_content_line(new_line)
17
+ @content = add_line(@content, new_line)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module PnoteClient
2
+ module Documents
3
+ class Pnote
4
+ attr_reader :chapters, :images
5
+
6
+ def initialize()
7
+ @chapters = []
8
+ @images = []
9
+ end
10
+
11
+ def add_chapter(new_chapter)
12
+ @chapters << new_chapter
13
+ end
14
+
15
+ def add_image(new_image)
16
+ @images << new_image
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module PnoteClient
2
+ module Utils
3
+ module StringUtil
4
+
5
+ def add_line(origin, new_line, delimiter = "\n")
6
+ return [origin, new_line].reject {|e| e.nil?}.join(delimiter)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module PnoteClient
2
+ VERSION = "1.0.1"
3
+ end