pnote_client 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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